The labs on this site need JavaScript to run. The same content is written out below.
Learn › Spring › Spring Boot
Spring Boot auto-configuration
Why do beans appear when all you did was add a dependency?
When an application starts, Spring Boot goes through a set of configuration classes prepared in advance, one by one, and decides "if this condition is met, register this bean". The conditions are mainly which libraries are on the classpath and whether the developer has registered the same bean.
Checked against documentation and standards · The official Spring Boot documentation
Concepts in this lab
- Spring Boot auto-configuration
- This Spring Boot feature looks at the libraries on the classpath and at the configuration values, and automatically registers the beans that are needed. For example, if a JDBC driver and connection details are present, it configures a DataSource automatically. Each auto-configuration has conditions for when it applies, and if the developer registers a bean of the same kind directly, the part of the auto-configuration that creates that bean does not apply.
- Starter
- This is a Spring Boot set of dependencies that groups the libraries needed for a particular feature in versions that are compatible with each other. Adding just the web one (spring-boot-starter-web up to Spring Boot 3, spring-boot-starter-webmvc since Spring Boot 4) brings in Spring MVC, JSON processing, embedded Tomcat, and more. It saves you the work of resolving version conflicts between libraries yourself.
- Embedded server
- This is a web server (Tomcat by default) that is included inside a Spring Boot application and runs together with it. You can run the application with a single java -jar command, without the steps of installing a server separately and deploying the application to it.
- @Configuration and @Bean
- @Configuration marks a configuration class that contains bean definitions, and the object returned by each @Bean method inside it is registered as a bean. Use them when you need to make a bean from a class in an external library that you cannot modify, or when you need to control the creation process yourself. Classes that you write yourself are usually registered with @Component or a related annotation.
- Component scanning
- This feature finds the classes under a given package that carry @Component or one of its related annotations (such as @Service, @Repository, and @Controller) and registers them as beans automatically. In Spring Boot, the default target is the package of the class annotated with @SpringBootApplication and its subpackages.
Try these
- Default settings — The web and JPA starters. All the beans that are needed are created, and you register none yourself.
- Leaving out the database URL — The driver is MySQL, but there is no connection URL. Startup fails.
- With H2, even without a URL — When Spring Boot finds an embedded database, it creates an in-memory database for you.
- Registering your own DataSource — The auto-configuration backs away, and the one you created is used.
- Registering your own JsonMapper — The JsonMapper that Spring Boot would have created is not registered.
- Removing the web starter — Neither Tomcat nor DispatcherServlet is created.
Running with the default settings
- The application starts. The @EnableAutoConfiguration inside @SpringBootApplication loads the list of auto-configuration classes that ship with Spring Boot (a little over 100). Your own @Configuration and @Component classes are registered first, and then the conditions of the auto-configurations are evaluated one by one.
- Embedded server auto-configuration: The web starter brought in the Tomcat library with it. Tomcat is on the classpath, so Spring Boot registers the bean that starts an embedded Tomcat. That is why the application runs from a single jar, with no separate application server to install.
- Spring MVC auto-configuration: The DispatcherServlet class is present, so Spring Boot registers DispatcherServlet and the default MVC components (message converters, handler mappings, and so on).
- Jackson auto-configuration: You have not registered a JsonMapper yourself, so a JsonMapper with the default settings is registered.
- DataSource auto-configuration: The JDBC classes are present, and you have not registered a DataSource yourself. Spring Boot creates a HikariCP connection pool with the connection URL from the settings and registers it.
- JPA auto-configuration: It uses the DataSource prepared earlier to register an EntityManagerFactory and a transaction manager for JPA. Auto-configurations also have an order among themselves, so this one is evaluated after the DataSource is ready.
- Spring Data JPA auto-configuration: It finds the interfaces that extend JpaRepository, creates an implementation object for each of them, and registers it as a bean.
- The remaining auto-configurations: Their libraries are not on the classpath, so most of them fail their conditions. Many configurations are prepared, but the only ones actually applied are those that match the dependencies you added.
Result of this run
- Auto-configuration decides on two criteria: whether the library is on the classpath (@ConditionalOnClass), and whether the developer has already registered a bean of the same type (@ConditionalOnMissingBean). The role of a starter is to bring in the set of libraries that are needed all at once, which satisfies the first condition.
- An auto-configuration with such a condition (@ConditionalOnMissingBean) backs away when you register a bean of the same type yourself. Start with the defaults, and register yourself only the parts that you want to change. To see which auto-configurations were applied or left out, and why, run the application with the --debug option, which prints a conditions report.
Code
// build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webmvc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
}
# application.yml
spring.datasource.url: jdbc:mysql://localhost:3306/shop
// An auto-configuration class looks like this inside
// @ConditionalOnClass(DataSource.class) only when the class is on the classpath
// @ConditionalOnMissingBean(DataSource.class) only when you have not registered the bean yourself
Assumptions of this model
This lab picks only a few representative auto-configurations and simplifies them. The real class names and conditions are more fine-grained (for example, DataSourceAutoConfiguration, JacksonAutoConfiguration, HibernateJpaAutoConfiguration). The meaning of the conditions and the principle that "auto-configuration backs away when you have registered the bean yourself" follow the explanation in the official Spring Boot documentation. The dependency names are those of Spring Boot 4 (up to Spring Boot 3, the web starter was named spring-boot-starter-web). These results were not checked against a running Spring Boot application. That the Jackson auto-configuration registers a JsonMapper-type bean with @ConditionalOnMissingBean was verified by opening the class files of spring-boot-jackson 4.1.1 on this PC.
Previous lab: REST APIs and message converters · Next lab: Configuration precedence