Core Capabilities of Spring Boot
-
Starter Dependencies: Spring Boot groups commonly used libraries into cohesive modules called starters (e.g.,
spring-boot-starter-web). Each starter bundles transitive dependencies with compatible versions, enabling declarative inclusion via a single artifact. -
Convention-over-configuration: Configuration is simplified through Java-based configuration classes and purpose-built annotations (
@SpringBootApplication,@RestController, etc.), reducing boilerplate XML or property files. -
Auto-configuration: At startup, Spring Boot inspects the classpath and application context to conditionally register beans—leveraging
@ConditionalOnClass,@ConditionalOnMissingBean, and similar annotations—minimizing manual wiring. -
Embedded Runtime Support: Applications package as executable JARs containing an embedded servlet container (Tomcat by default, with alternatives like Jetty or Undertow). No external server setup is required—just a JVM.
How Dependency Versions Are Managed
Why do many dependencies omit epxlicit <version> tags?
This behavior stems from Maven’s dependency management inheritance. In a typical Spring Boot project, the pom.xml declares:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
</parent>
The spring-boot-starter-parent POM itself inherits from spring-boot-dependencies, which defines a comprehensive <dependencyManagement> block. For example:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- dozens more -->
</dependencies>
</dependencyManagement>
This centralized version catalog ensures consistent alignment across the ecosystem—no need to declare versions for managed artifacts unless overriding is intentional.
Additionally, spring-boot-starter-parent sets foundational defaults:
- Java language level (
<java.version>17</java.version>) - UTF-8 encoding for source and reporting
- Resource filtering for
application*.propertiesandapplication*.ymlfiles - Standardized plugin configurations (e.g.,
maven-compiler-plugin,maven-resources-plugin)
Where Do Runtime JARs Actually Come From?
Starters themselves are not fat libraries—they’re thin POMs declaring what to pull in transitively.
Take spring-boot-starter-web as an illustration. Its effective dependency graph includes:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
</dependencies>
Each listed artifact resolves its own dependencies recursively. For instance, spring-boot-starter-tomcat pulls in tomcat-embed-core, tomcat-embed-el, and related modules. The version of each is governed by the spring-boot-dependencies BOM—ensuring compatibility without manual coordination.
Third-party starters (e.g., mybatis-spring-boot-starter, micrometer-tracing-starter) follow the same pattern: they declare dependencies but rely on Spring Boot’s parent POM or their own BOM to pin versions. When using non-official starters, always verify whether they publish a *-dependencies BOM and declare it in <dependencyManagement> if needed.