2024.4.25 Thursday
Contents
- 5. Principles of Auto-Configuration
- 5.1. What can be written in configuration files and how?
- 5.2. Analyzing the Principles of Auto-Configuration
- 6. Spring Boot: Exploring Web Development
5. Principles of Auto-Configuration
5.1. What can be written in configuration files and how?
There are numerous configurations in the Spring Boot official documentation, which we cannot remember all.
5.2. Analyzing the Principles of Auto-Configuration
5.2.1. Follow these steps
5.2.1.1. src/main/java/com/p8/springboot02config/Springboot02ConfigApplication.java
5.2.1.2. @SpringBootApplication (line 6)
5.2.1.3. @EnableAutoConfiguration (line 56) automatically imports configurations
5.2.1.4. AutoConfigurationImportSelector (line 84) enter AutoConfigurationImportSelector.java
5.2.1.5. getAutoConfigurationEntry (line 101)
5.2.1.6. getCandidateConfigurations (line 125)
5.2.1.7. getSpringFactoriesLoaderFactoryClass (line 183)
5.2.1.8. @EnableAutoConfiguration (line 197) marks all the following classes
5.2.1.9. loadFactoryNames (line 183) this annotation loads configurations
5.2.1.10. loadSpringFactories (line 69)
5.2.1.11. loadSpringFactories (line 72)
5.2.1.12. Enumeration urls = classLoader.getResources(“META-INF/spring.factories”); (line 80)
Iterate through all resources, pointing to META-INF/spring.factories
5.2.1.13. Encapsulate the read data into Properties (line 85) then return and use
5.2.1.14. Essentially, the scanned packages will all be automatically configured, ultimately pointing to the configuration files
5.2.2. We use HttpEncodingAutoConfiguration (HTTP Encoding Auto Configuration) as an example to explain the principles of auto configuration
Note: This can be found in the tutorial, but may not be found in your own spring.factories due to version differences.
package com.p8.springboot02config.pojo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
// This indicates that it is a configuration class, just like previously written configuration files, and can also add components to the container;
@Configuration
// Auto configure properties
// Activate the ConfigurationProperties feature for the specified class;
// Enter this HttpProperties to see, binding the values in the configuration file with HttpProperties;
// and add HttpProperties to the IoC container
@EnableConfigurationProperties({HttpProperties.class})
// Spring's underlying @Conditional annotations
// Based on different conditions, if specified conditions are met, the entire configuration in this class becomes effective;
// The meaning here is to check if the current application is a web application, if yes, then this configuration class is effective
@ConditionalOnWebApplication(
type = Type.SERVLET
)
// Checks if the project contains this class CharacterEncodingFilter; a filter for solving encoding issues in Spring MVC;
@ConditionalOnClass({CharacterEncodingFilter.class})
// Checks if a configuration exists in the configuration file: spring.http.encoding.enabled;
// If it doesn't exist, the condition is also satisfied
// Even if we do not configure spring.http.encoding.enabled=true in our configuration file, it defaults to being effective;
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
// It is already mapped to the Spring Boot configuration files
private final Encoding properties;
// When there is only one constructor with arguments, the value for the parameter will be taken from the container
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}
// Adds a component to the container, some values of this component need to be obtained from properties
@Bean
@ConditionalOnMissingBean // Check if 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.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
return filter;
}
//......
}
5.2.2.1. In one sentence: The configuration class becomes effective based on certain conditions!
5.2.2.1.1. Once this configuration class is activated, it will add various components to the container;
5.2.2.1.2. The properties of these components are obtained from the corresponding properties classes, and each property within these classes is bound to the configuration file;
5.2.2.1.3. All the properties that can be configured in the configuration file are encapsulated within the xxxxProperties class;
5.2.2.1.4. What can be configured in the configuration file can be referred to by looking at the corresponding properties class for a feature
5.2.2.1.5.
// Bind specified values from the configuration file to bean properties @ConfigurationProperties(prefix = "spring.http") public class HttpProperties { // .....}
5.2.2.1.6. Let’s try the prefix in the configuration file and look at the prompts!
This is the principle of auto-configuration!
5.2.3. The Essence
5.2.3.1. Spring Boot on startup loads numerous auto-configuration classes
5.2.3.2. We check if the functionality we need is within the auto-configuration classes provided by default in Spring Boot;
5.2.3.3. We then look at what components are configured in this auto-configuration class; (as long as the components we need are included, we do not need to configure them manually)
5.2.3.4. When adding components to the container via auto-configuration classes, some properties are fetched from properties classes. We just need to specify these properties’ values in the configuration file;
5.2.3.5. xxxxAutoConfiguration: Auto-configuration class; adds components to the container
5.2.3.6. xxxxProperties: Encapsulates properties in the configuration file.
5.2.4. Understanding: @Conditional
5.2.4.1. After understanding the principles of auto-configuration, we focus on a detail, auto-configuration classes must be effective under certain conditions;
5.2.4.2. @Conditional derived annotations (the original effect of Spring’s native @Conditional)
5.2.4.3. Function: Only if the condition specified by @Conditional is met, the components are added to the container, and all content in the configuration becomes effective;
@Conditional derived annotation | Function (checks if the specified condition is met) |
---|---|
@ConditionalOnJava | If the system’s Java version meets the requirements |
@ConditionalOnBean | If the specified Bean exists in the container |
@ConditionalOnMissingBean | If the specified Bean does not exist in the container |
@ConditionalOnExpression | If a specified SpEL expression is met |
@ConditionalOnClass | If the specified class exists in the system |
@ConditionalOnMissingClass | If the specified class does not exist in the system |
@ConditionalOnSingleCandidate | If there is only one specified Bean in the container or it is preferred |
@ConditionalOnProperty | If a specified property in the system has a specified value |
@ConditionalOnResource | If a specified resource file exists in the classpath |
@ConditionalOnWebApplication | If the current environment is a web environment |
@ConditionalOnNotWebApplication | If the current environment is not a web environment |
@ConditionalOnJndi | If a specified item exists in JNDI |
5.2.4.4. With so many auto-configuration classes, they must be effective under certain conditions; meaning, we load many configuration classes, but not all are effective.
How do we know which auto-configuration classes are effective?
5.2.4.5. We can enable the debug=true property; this allows the console to print an auto-configuration report, making it convenient for us to know which auto-configuration classes are effective;
# Enable Spring Boot's debug class
debug=true
5.2.4.6. Positive matches: (Auto-configuration classes that are enabled: positive matches)
5.2.4.7. Negative matches: (Auto-configuration classes that are not enabled, unsuccessful matches: negative matches)
5.2.4.8. Unconditional classes: (Classes without conditions)
5.2.4.9. 【Demonstration: Review the output log】
5.2.4.10. Master and understand the principles, and you can adapt to any changes!
5.2.5. Modify application.yaml, rerun Springboot02ConfigApplication
# What can be written in a configuration file?
# The connection between this and spring.factories
# spring:
# mvc:
# date-format: This method is deprecated; previously, clicking on date-format would show details, now it cannot
debug: true
In the Console tab, the CONDITIONS EVALUATION REPORT will show which configurations are “Positive matches” (effective) and which are “Negative matches” (ineffective).
6. Spring Boot: Exploring Web Development
6.1. Consideration: What has Spring Boot configured for us? Can we modify it? What can we modify? Can it be extended?
6.1.1. Common filenames include
6.1.1.1. XxxxAutoConfiguration: Automatically configures components to the container (may be disabled due to unmet conditions)
6.1.1.2. XxxxProperties: Auto-configuration class, assembling content customized in the configuration file
6.1.2. Issues to resolve
6.1.2.1. Importing static resources
6.1.2.2. Writing the homepage
6.1.2.3. No jsp -> switch to using the Thymeleaf template engine
6.1.2.4. Assembling extensions for SpringMVC
6.1.2.5. CRUD operations
6.1.2.6. Interceptors
6.1.2.7. Internationalization (Chinese and English)