A, @ SpringBootApplication

This note is an abbreviation of the following three notes:

  • @EnableAutoConfiguration
  • @ComponentScan
  • @SpringBootConfiguration

It marks the class on which the main method is located:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class Application {
 
    public static void main(String[] args) { SpringApplication.run(Application.class, args); }}Copy the code

Second, @ EnableAutoConfiguration

The annotations enable global auto-configuration. Spring Boot processes the meta-INF/Spring.Factories file under the JAR. The content in the file might look like this:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration
Copy the code

As you can see, this file specifies which configuration classes should be automatically loaded.

Third, @ SpringBootConfiguration

This annotation serves the same purpose as the @Configuration annotation, marking a class as a Spring Boot Configuration class.

Fourth, @ EnableAutoConfiguration

If we don’t want to use @enableAutoConfiguration to enable global auto-configuration, and sometimes we want to use only a subset of the configuration, we can import a given configuration class using the @ImportautoConfiguration annotation:

@ComponentScan("path.to.your.controllers")
@ImportAutoConfiguration({WebMvcAutoConfiguration.class
    ,DispatcherServletAutoConfiguration.class
    ,EmbeddedServletContainerAutoConfiguration.class
    ,ServerPropertiesAutoConfiguration.class
    ,HttpMessageConvertersAutoConfiguration.class})
public class App 
{
    public static void main(String[] args) 
    { SpringApplication.run(App.class, args); }}Copy the code

5. Specify the loading sequence of the configuration

If our configuration depends on another configuration, we can specify the loading order of the configuration using the following three annotations:

  • @AutoConfigureBeforeIs loaded before a Bean is loaded.
  • @AutoConfigureAfterIs loaded after a Bean is loaded.
  • @AutoConfigureOrderThis annotation can accept an integer to explicitly specify the load order, which corresponds to@OrderIt has the same semantics.

Example: Use @AutoConfigureAfter

@Configuration
@AutoConfigureAfter(CacheAutoConfiguration.class)
@ConditionalOnBean(CacheManager.class)
@ConditionalOnClass(CacheStatisticsProvider.class)
public class RedissonCacheStatisticsAutoConfiguration 
{
    @Bean
    public RedissonCacheStatisticsProvider redissonCacheStatisticsProvider(a){
        return newRedissonCacheStatisticsProvider(); }}Copy the code

In the code above, only after the completion of the loading CacheAutoConfiguration RedissonCacheStatisticsAutoConfiguration loading.

Conditional loading and configuration of beans

Spring Boot automatically configures itself by loading Configuration classes annotated by @Configuration. To provide greater extensibility, Spring Boot provides a series of @Conditional annotations to constrain the loading timing of configurations.

6.1 Load the configuration based on Bean existence

  • @ConditionalOnBeanWhen the specified Bean exists in the Spring container, the corresponding configuration is loaded;
  • @ConditionalOnMissingBeanWhen the specified Bean does not exist in the Spring container, the corresponding configuration is loaded.

They can take a Bean name or Class as an argument.

Example: use @conditionalonmissingBean

@Configuration
public class MyAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public MyService myService(a) {... }}Copy the code

In the above code, a Bean of type MyService is injected when it does not exist in the Spring container.

6.2 Load the configuration based on the existence of a Class

  • @ConditionalOnClassThe configuration is loaded only when the specified class exists.
  • @ConditionalMissingClassThe configuration is loaded only when the specified class does not exist.

They can take a Class or string classpath as an argument.

Example: use @conditionalonClass

@Configuration
// Some conditions
public class MyAutoConfiguration {

    // Auto-configured beans

    @Configuration
    @ConditionalOnClass(EmbeddedAcmeService.class)
    static class EmbeddedConfiguration {

        @Bean
        @ConditionalOnMissingBean
        public EmbeddedAcmeService embeddedAcmeService(a) {... }}}Copy the code

In the code above, the class EmbeddedAcmeService is only loaded if it exists and it doesn’t exist in the Spring container.

Note that since Spring uses ASM for dynamic loading, these annotations will work even if they specify a type that does not exist at runtime.

However, the JVM will throw a ClassNotFoundException if all three conditions occur together:

  • @Bean,@ConditionalOnClassor@ConditionalMissingClassAnnotations on the same method;
  • @BeanThe annotated method returns type and@ConditionalOnClassor@ConditionalMissingClassThe same type is specified in the annotation;
  • At run time, this type is inclasspathDoes not exist in.

6.3 Load the configuration based on whether it is a Web application

  • @ConditionalOnNotWebApplicationThe configuration is loaded only when the current application is not a Web application.
  • @ConditionalOnWebApplicationThe configuration is loaded only when the current application is a Web application.

Spring Boot identifies an application as a Web application only when at least one of the following conditions is true:

  • The context used isWebApplicationContext;
  • There is a Bean that hassessionScope;
  • There areStandardServletEnvironment.

6.4 Loading a Configuration Based on a Property

The @conditionalonProperty annotation checks the value of the Spring environment variable and only loads the configuration if the condition is true.

Example: use @conditionalonProperty

@Configuration
public class DataSourceConfiguration {
    @Bean
    @ConditionalOnProperty(name = "env", havingValue = "local")
    DataSource localDataSource(a) 
    {
        // ...
    }
    
    @Bean
    @ConditionalOnProperty(name = "env", havingValue = "prod")
    DataSource prodDataSource(a) 
    {
        // ...}}Copy the code

The above code demonstrates the dynamic loading of a DataSource into the Spring container by checking the value of the env option in the application.properties file.

6.5 Loading configurations Based on the Existence of resources

ConditionalOnResource can load the configuration based on whether the specified resource exists.

Example: use @conditionalonResource

@Configuration
public class VendorConfiguration {
    @ConditionalOnResource(resources = "classpath:vendor.properties")
    Properties additionalProperties(a) 
    {
        // Do some processing on vendor.properties
        // ...}}Copy the code

In the code above is only when the file classpath: vendor. The properties to exist is to deal with it.

6.6 Loading configuration Based on SpEL Expressions

The @conditionalonExpression annotation checks the result of the SpEL expression and only loads the configuration if the expression is true.

Example: replace @conditionalonProperty with @conditionalonexpression

@Configuration
public class DataSourceConfiguration {
    @Bean
    @ConditionalOnExpression("${env} && ${havingValue == 'local'}")
    DataSource localDataSource(a) 
    {
        // ...
    }
    
    @Bean
    @ConditionalOnExpression("${env} && ${havingValue == 'prod'}")
    DataSource prodDataSource(a) 
    {
        // ...}}Copy the code

ConditionalOnExpression replaces @conditionalonProperty with @conditionalonExpression, which also allows dynamic loading of the DataSource.

6.7 Load the configuration based on the Cloud Platform

Annotations @ ConditionalOnCloudPlatform is capable of detecting bearing Spring Boot application platform for the cloud, when the application to run in the specified cloud platform will load the corresponding configuration, this annotation support for these common cloud platform:

  • Cloud Foundry
  • Heroku
  • Kubernetes
  • SAP

Example: using the @ ConditionalOnCloudPlatform

@Configuration
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
public class CloudConfigurationExample 
{
  @Bean
  public MyBean myBean(MyProperties properties) 
  {
    return newMyBean(properties.getParam); }}Copy the code

In the above code, MyBean is loaded into the Spring container only if our Spring Boot program is running on the K8S platform.

In addition, there are four enumerated values in the enumeration CloudPlatform:

  • CLOUD_FOUNDRY
  • HEROKU
  • KUBERNETES
  • SAP

References:

Spring Boot Features —— Creating Your Own Auto-configuration