SpringBoot AutoConfiguration Principle

Keywords: Java Spring Spring Boot

Official SpringBoot Documentation There are a lot of configurations, and we can't remember them all

1. Find Configuration Directory

1. Enter the Startup Class at @SpringBootApplication

2. Enter @EnableAutoConfiguration under this comment

3. AutoConfigurationImportSelector class imported into @Import({AutoConfigurationImportSelector.class})

4. Find the getAutoConfigurationEntry method for this class and enter the getCandidateConfigurations method

5. Enter the SpringFactoriesLoader class

6. Load and instantiate a factory implementation of a given type from FACTORIES_RESOURCE_LOCATION using a given class loader.

  • Generic Factory Loading Mechanism Used Inside Framework
  • Read files from multiple jar package specific locations under classpath and initialize classes
  • File content must be in kv form, which is the property type
  • key is the fully qualified name [abstract class interface], value is the implementation, and multiple implementations are split by commas [,]


7. Find the configuration directory spring.factories

2. Review configuration properties

In yaml grammar learning, we usually need to configure information in property. We usually get the configuration from the configuration file by using the @ConfigurationProperties(pefix="prefix") annotation, as follows:

1. Write Entity Class Person

/*
@ConfigurationProperties Effect:
Map the value of each property configured in the configuration file to this component;
Tell SpringBoot to bind all the properties in this class to the related configurations in the configuration file
 Parameter prefix = "person": Map all the attributes below person in the configuration file one to one
*/
@Component //Register bean s
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> map;
    private List<Object> list;
    private Dog dog;
}

2. Configuration information in application.yaml

person:
  name: cyo_${random.uuid}
  age: 3
  happy: false
  birth: 2021/1/24
  map: {k1: v1,k2: v2}
# hello: lian

  list:
    - code
    - girl
    - music
  dog:
    name: ${person.hello:other}_Manlong
    age: 3

3. Write test classes

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    Person person; //Auto-inject person

    @Test
    public void contextLoads() {
        System.out.println(person); //Print person information
    }

}

4. Successful Injection

Person{
	name='cyo_063dd484-575e-4c00-a4ad-eb6297a66a66', 
	age=3, 
	happy=false, 
	birth=Sun Jan 24 00:00:00 CST 2021, 
	map={k1=v1, k2=v2}, 
	list=[code, girl, music], 
	dog=Dog{name='other_Manlong', age=3}}

3. Automatic Configuration Principle Process

Import the corresponding start in pom.xml for the automatic configuration to take effect

The META-INF files of mybatis-spring-boot-starter, spring-boot-starter-web and other components contain spring.factories files.

In the auto-configuration module, SpringFactoriesLoader collects the full name of a class in a file and returns an array of the full name of the class. The returned full name of the class is instantiated by reflection, forming a specific factory instance that generates the bean s the component needs.

Sample Analysis

Explain the principle of automatic configuration with **HttpEncoding AutoConfiguration** (Http Encoding AutoConfiguration) as an example;

//Indicates that this is a configuration class and that components can be added to containers just like previously written configuration files;
@Configuration(
    proxyBeanMethods = false
) 

//Starts the ConfigurationProperties function for the specified class;
  //Go into this ServerProperties view and bind the corresponding values in the configuration file to ServerProperties;
  //And add ServerProperties to the ioc container
@EnableConfigurationProperties({ServerProperties.class}) 

//Spring Bottom @Conditional Comment
  //Based on different conditions, if the specified conditions are met, the configuration within the entire configuration class will take effect.
  //This means to determine if the current application is a web application and, if so, whether the current configuration class is valid
@ConditionalOnWebApplication(
    type = Type.SERVLET
)

//Determine if the current project has this type of CharacterEncoding Filter; a filter for scrambling in SpringMVC;
@ConditionalOnClass({CharacterEncodingFilter.class})

//Determine if a configuration exists in the configuration file: spring.http.encoding.enabled;
  //If it doesn't exist, the judgment is valid
  //Even if spring.http.encoding.enabled=true is not configured in our configuration file, it will take effect by default;
@ConditionalOnProperty(
    prefix = "server.servlet.encoding",
    value = {"enabled"},
    matchIfMissing = true
)

public class HttpEncodingAutoConfiguration {
    //He has mapped to the SpringBoot profile
    private final Encoding properties;
    //With only one parameter constructor, the value of the parameter is taken from the container
    public HttpEncodingAutoConfiguration(ServerProperties properties) {
        this.properties = properties.getServlet().getEncoding();
    }
    
    //Add a component to the container whose values need to be obtained from properties
    @Bean
    @ConditionalOnMissingBean //Judging 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(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE));
        return filter;
    }
    //. . . . . . . 
}

One sentence summary: Based on the current different conditions, determine whether this configuration class is valid or not!

  • This configuration class takes effect; it adds components to the container.
  • The properties of these components are derived from the corresponding properties classes, each of which is bound to the configuration file;
  • All properties that can be configured in the configuration file are encapsulated in the xxxxProperties class;
  • What a profile can configure refers to this property class corresponding to a function
//Get the specified value from the configuration file and the properties of the bean to bind
@ConfigurationProperties(prefix = "servlet.server") 
public class ServerProperties{
    // .....
}

Let's try the prefix in the profile for tips!

This is how automatic assembly works!

quintessence

1. SpringBoot startup loads a large number of auto-configuration classes

2. Let's see if the functions we need are in the AutoConfiguration class written by default in SpringBoot.

3. Let's look again at what components are configured in this auto-configuration class; (As long as the components we want to use are in it, we don't need to configure them manually anymore)

4. When you add components to an auto-configuration class in a container, you get some properties from the properties class. We only need to specify the values of these properties in the configuration file.

**xxxAutoConfigurartion: Auto-configure classes; **Add components to containers

xxxxProperties: Encapsulates related properties in the configuration file;

Learn about @Conditional

After understanding the principle of auto-assembly, let's focus on a detail issue. Auto-configuration classes must be in effect under certain conditions.

@Conditional Derived Annotation (Native @Conditional Role of Spring Annotation Edition)

** Role: ** The condition specified by @Conditional must be valid before adding components to the container and all the contents of the configuration will take effect;

So many automatic configuration classes have to be in effect under certain conditions; that is, we loaded so many configuration classes, but not all of them worked.

How do we know which automatic configuration classes work?

We can enable the debug=true property to allow the console to print auto-configuration reports so that we can easily know which auto-configuration classes are in effect;

#Open the debugging class for springboot
debug: true

Positive matches:(auto-configuration class enabled: positive matches)

Negative matches:(No startup, no matching successful autoconfiguration class: negative matching)

Unconditional classes:(unconditional class)

[Demo: View the log of the output]

Reference material

This article is mainly about notes taken to watch the video of the encounter of psychotics in order to review
Video address:
[1] https://www.bilibili.com/video/BV1PE411i7CV?spm_id_from=333.999.0.0
[2] spring boot(2): Startup principle analysis: https://www.cnblogs.com/xiaoxi/p/7999885.html

Posted by kylebud on Sat, 25 Sep 2021 09:11:20 -0700