How is the automatic configuration of SpringBoot implemented

Posted by shuka79 on Wed, 22 Dec 2021 19:49:33 +0100

catalogue

1, What is SpringBoot?

2, What are the advantages of SpringBoot?

3, Principle analysis of automatic configuration

1, What is SpringBoot?

SpringBoot is a sub project under the open source organization of Spring. It is a one-stop solution for Spring components. It simplifies the difficulty of using Spring, saves a lot of cumbersome configuration, and provides a variety of Starter starters, which can be used by developers quickly.

2, What are the advantages of SpringBoot?

(1) Easy to get started and improve development efficiency;

(2) Out of the box, avoiding cumbersome configuration;

(3) No code generation, no xml configuration;

(4) Provide a series of non business functions common to the project, such as embedded server, security management, operation data monitoring and operation status inspection;

(5) Avoid a large number of conflicts between Maven imports and versions;

3, Principle analysis of automatic configuration

We found a @ SpringBootApplication annotation on the SpringBoot boot class

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
...}

As can be seen from the above code, there are several annotations on SpringBootApplication, which need to be paid attention to:
@SpringBootConfiguration: mark the current class as the Configuration class, and combine the @ Configuration annotation to realize the function of the Configuration file
@EnableAutoConfiguration: turn on auto configuration
@ComponentScan: Spring component scan, which scans the beans in the same level package and lower level package of the main class
Let's analyze @ EnableAutoConfiguration first

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
...}

@Among the several annotations on EnableAutoConfigurationd, the most critical one is @ Import(EnableAutoConfigurationImportSelector.class). With the help of EnableAutoConfigurationImportSelector, @EnableAutoConfiguration can help SpringBoot applications load all qualified @ Configuration configurations into the IoC container created and used by the current SpringBoot: the Configuration function imported through @ Import(AutoConfigurationImportSelector.class),
The method getCandidateConfigurations in AutoConfigurationImportSelector obtains the collection of class names of the classes to be configured. This collection is all the classes that need to be configured automatically. The key to whether to configure or not is meta-inf / spring Does the configuration information exist in the factories file

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

As shown in the figure below, you can see that the full paths of all classes to be configured are in the file. Each line is configured, and multiple class names are separated by commas, while \ means to ignore line feed

Let's take httpencoding autoconfiguration (HTTP encoding autoconfiguration) as an example to explain the principle of autoconfiguration

@Configuration //Indicates that this is a configuration class
@EnableConfigurationProperties(HttpEncodingProperties.class) //Starts the of the specified class
    ConfigurationProperties Function; The corresponding values in the configuration file and HttpEncodingProperties Bind; And put
    HttpEncodingProperties Add to ioc In container
@ConditionalOnWebApplication //Spring bottom @ Conditional annotation (spring annotation version), according to different conditions, if
    If the specified conditions are met, the configuration in the entire configuration class will take effect; Judge whether the current application is web Application. If yes, the current configuration class is generated        effect
@ConditionalOnClass(CharacterEncodingFilter.class) //Determine whether the current project has this class
    CharacterEncodingFilter;SpringMVC A filter for garbled code resolution in;
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing =
true) 
    //Determine whether there is a spring. In the configuration file http. encoding. enabled; If it does not exist, the judgment is also valid
    //Even if pring. Is not configured in our configuration file http. encoding. Enabled = true, which is also effective by default;
public class HttpEncodingAutoConfiguration {
    //It has been mapped to the SpringBoot configuration file
    private final HttpEncodingProperties properties;
//When there is only one constructor with parameters, the value of the parameter will be taken from the container
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
    this.properties = properties;
}
@Bean //Add a component to the container. Some values of this component need to be obtained from properties
@ConditionalOnMissingBean(CharacterEncodingFilter.class) //Determine that the container does not have this component
public CharacterEncodingFilter characterEncodingFilter() {
    CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
    filter.setEncoding(this.properties.getCharset().name());
    filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
    filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
    return filter;
}

Determine whether the configuration class is effective according to different current conditions;

All properties that can be configured in the configuration file are encapsulated in the xxproperties class. What can be configured in the configuration file can refer to the property class corresponding to a function.

That is, once the configuration class takes effect, the configuration class will add various components to the container. The properties of these components are obtained from the corresponding properties class, and each property in these classes is bound to the configuration file;

Summary:

Simply put, the automatic configuration principle of SpringBoot is:

When SpringBoot starts, meta-inf / Spring will be found through the @ EnableAutoConfiguration annotation All automatic configuration classes in the factories configuration file are loaded. These automatic configuration classes are named at the end of xxxAutoConfiguration. In fact, they are Spring container configuration classes in the form of JavaConfig. They can obtain the Properties configured in the configuration file through the classes named at the end of Properties, such as serve Port, and the xxproperties class is bound to the corresponding Properties in the configuration file through the @ ConfigurationProperties annotation.

Topics: Java Spring Boot