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-webmvc is present, it configures a DispatcherServlet and an embedded web server for you. If a DataSource class 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.jar starts 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:

HTML
<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:

Java
@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):

Bash
./mvnw spring-boot:run
Plaintext
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: 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:

Bash
./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 DispatcherServlet bean), which either conflicts with or silently shadows the auto-configured one.
  • Moving the main @SpringBootApplication class 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.