Spring Boot Auto Configuration
@Import is used to add more Spring configurations to the application context.
@Import that points to AutoConfigurationImportSelector. However, in addition to classes annotated with @Configuration, @Import may also refer to classes that implement either ImportSelector or ImportBeanDefinitionRegistrar. Both are Spring interfaces that allow you to influence the structure of the application context.
The ImportSelector is interesting for the understanding of Spring Boot, because the class AutoConfigurationImportSelector implements exactly this interface. An ImportSelector can programmatically decide which Spring configurations should be added to the application context. This mechanism is used for loading the Auto Configurations.
The AutoConfigurationImportSelector uses another, lesser-known Spring feature here: the SpringFactoriesLoader and the associated META-INF/spring.factories files. The spring.factories are files in properties format, with a class name as key and a list of associated classes, each separated by a comma. Listing 3 shows an excerpt from Spring Boot’s META-INF/spring.factories.
EXTRACT FROM META-INF/SPRING.FACTORIES
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
Now that we know how Auto Configurations are found. But what exactly an Auto Configuration actually is?
All entries that appear in the spring.factories for EnableAutoConfiguration are themselves normal Spring configurations (classes, annotated with @Configuration).
What makes Auto Configurations so special is when they are loaded. The AutoConfigurationImportSelector is executed very late in the application context. So @Import declarations are taken into account beforehand, and the component scan also takes place before. Thus the Application Context already contains all Bean definitions of the application before the Auto Configurations are considered. This makes it possible to attach conditions to the Bean declarations in the Auto Configurations. These conditions are described by @ConditionalOn annotations (box: “Overview of @ConditionalOn Annotations”).
Overview of @ConditionalOn Annotations Spring Boot offers many different @ConditionalOn annotations for different purposes. The most common annotations are described below.
@ConditionalOnProperty
A property is expected, which may also have a certain value. This condition is suitable, for example, for implementing feature toggles.
@ConditionalOnBean, @ConditionalOnMissingBean
With these annotations, it can be expressed that a Bean of a certain type exists in the application context (@ConditionalOnBean) or that there are no Beans of this type (@ConditionalOnMissingBean).
@ConditionalOnClass, @ConditionalOnMissingClass
Similar to the annotations @ConditionalOnBean and @ConditionalOnMissingBean, these annotations define an expectation: either that a class is available on the classpath or that it is not.
@ConditionalOnJava
If certain configurations or Beans are dependent on a certain Java runtime version, this can be expressed using this annotation.
@ConditionalOnResource
This condition expects that resources are available. All resource paths supported by Spring are possible, for example, classpath:/index.html.
@ConditionalOnWebApplication, @ConditionalOnNotWebApplication
Bean declarations can be created with these annotations, depending on whether the application is a web application or not. With @ConditionalOnWebApplication you can additionally differentiate whether it is a servlet-based or reactive web application.