Spring Boot Introduction
Auto-configuration, starters, the embedded server, and what @SpringBootApplication actually composes.
What Spring Boot adds on top of Spring
The core Spring Framework solves dependency injection and wiring, but a real application still needs a lot of setup before it does anything useful: choosing and configuring a web server, declaring compatible versions of a dozen libraries, writing boilerplate @Configuration classes for common concerns, and packaging it all for deployment. Spring Boot removes that setup by being opinionated about defaults while staying fully built on top of ordinary Spring — nothing from the core Spring track stops applying inside a Boot app.
Three ideas make this possible:
- Auto-configuration — Spring Boot inspects what's on the classpath and configures sensible beans automatically. If
spring-webmvcis present, it configures aDispatcherServletand an embedded web server for you. If aDataSourceclass is on the classpath along with connection properties, it configures a connection pool. You can always override any auto-configured bean by defining your own. - Starters — curated dependency bundles. Instead of hunting down compatible versions of a web framework, a JSON library, a validation library, and a logging framework separately, you add one starter and get a tested, compatible set.
- Embedded server — the application packages its own server (Tomcat by default) inside an executable JAR. There's no separate application server to install and deploy to;
java -jar app.jarstarts a fully running web application.
spring-boot-starter-web
Adding one dependency pulls in everything needed for a web application — Spring MVC, an embedded Tomcat server, and Jackson for JSON:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Other common starters follow the same pattern: spring-boot-starter-data-jpa for Spring Data JPA + Hibernate, spring-boot-starter-security for Spring Security, spring-boot-starter-test for JUnit/Mockito/AssertJ. Each starter is designed to bring in mutually compatible versions, managed centrally by the Spring Boot parent POM (or BOM), so you don't pin individual library versions yourself.
The @SpringBootApplication annotation
Every Spring Boot application has one main class annotated @SpringBootApplication, which is itself a convenience annotation combining three others:
@SpringBootApplication
public class MyAppApplication {
public static void main(String[] args) {
SpringApplication.run(MyAppApplication.class, args);
}
}
| Composed annotation | What it does |
|---|---|
@SpringBootConfiguration |
Marks this class as a @Configuration class (itself a specialization of it) |
@EnableAutoConfiguration |
Turns on Spring Boot's auto-configuration mechanism |
@ComponentScan |
Scans this class's package and all sub-packages for @Component/@Service/@Repository/@Controller beans |
This is exactly why Spring Boot applications are conventionally structured with the main class at the root package (e.g. com.example.myapp.MyAppApplication), with everything else nested underneath — @ComponentScan's default scope covers the whole application tree without any extra configuration.
Running a Boot application
SpringApplication.run(...) starts the embedded server, initializes the ApplicationContext, runs auto-configuration, and brings the application up on a port (8080 by default):
./mvnw spring-boot:run
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::
Tomcat started on port(s): 8080 (http)
Started MyAppApplication in 1.842 seconds
Or, once built, as a self-contained executable JAR — the embedded server ships inside it, so there's nothing else to install on the target machine:
./mvnw clean package
java -jar target/myapp-0.0.1-SNAPSHOT.jar
Common mistakes
- Manually re-declaring beans that auto-configuration already provides (e.g. a hand-written
DispatcherServletbean), which either conflicts with or silently shadows the auto-configured one. - Moving the main
@SpringBootApplicationclass out of the root package "for organization," which breaks component scanning for anything outside its new, narrower package tree. - Pinning individual library versions manually instead of relying on the starter/parent-managed versions, reintroducing the exact compatibility problems starters exist to avoid.
- Confusing Spring Boot for a different framework from Spring — it's the same container and DI model, just with auto-configuration and packaging conveniences layered on.