SpringBoot auto configuration principle

Keywords: Java Spring Spring Boot

SpringBoot auto configuration principle

This section also analyzes the automatic configuration of SpringBoot from the source code and how to write the configuration file!

1. Review the operating principle

As can be seen from the previous operation principle of SpringBoot, SpringBoot implements automatic configuration through the AutoConfigurationImportSelector class. The hierarchical relationship is

// Main startup class
@SpringBootApplication
// Turn on automatic configuration
@EnableAutoConfiguration
// Import autoconfiguration selector class
@Import({AutoConfigurationImportSelector.class})
// Class
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes);
// The above method calls the loadFactoryNames method of the springfactoryesloader class
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader);
// The loadSpringFactories method continues to be called
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader);
// Method to load the URL from the specified place
Enumeration urls = classLoader.getResources("META-INF/spring.factories");

Finally, all configuration classes (candidate configurations) that may be loaded are obtained from the META-INF/spring.factories file, which is in the spring-boot-autoconfigure-2.5.4.jar package. Automatic configuration is realized by judging which configuration classes are to be loaded through the current running configuration of SpringBoot.

2. Automatic configuration principle

Find the HttpEncodingAutoConfiguration class (Http encoding autoconfiguration) in the spring.factories file and use it to continue to analyze the principle of autoconfiguration (because this configuration class is relatively short)

Part of the code of the HttpEncodingAutoConfiguration class indicates the role of these annotations through comments

// Indicates that this is a configuration class
@Configuration(proxyBeanMethods = false)
// Enable the ConfigurationProperties function of the corresponding class
@EnableConfigurationProperties(ServerProperties.class)
// This is the @ conditionalon... Annotation mentioned earlier to judge whether it meets the loading conditions
// Judge whether it is currently a Web application
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
// Determine whether the current project has a CharacterEncodingFilter class
@ConditionalOnClass(CharacterEncodingFilter.class)
// Judge whether the server.servlet.encoding configuration exists in the configuration file. It takes effect by default
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {

	private final Encoding properties;

	public HttpEncodingAutoConfiguration(ServerProperties properties) {
		this.properties = properties.getServlet().getEncoding();
	}

    // Add a component (bean) to the container, where the value may be obtained from properties
	@Bean
    // Determine whether this component (bean) exists in the container
	@ConditionalOnMissingBean
	public CharacterEncodingFilter characterEncodingFilter() {
		CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
		filter.setEncoding(this.properties.getCharset().name());
		filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
		filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
		return filter;
	}

	...
}

The annotation @ EnableConfigurationProperties(ServerProperties.class) deserves special attention. It corresponds to a property class ServerProperties. Click to see what it is

// The @ ConfigurationProperties annotation used before! It will find the server configuration in the configuration file!
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

	/**
	 * Server HTTP port.
	 */
	private Integer port;

	/**
	 * Network address to which the server should bind.
	 */
	private InetAddress address;
    
    // There are many, many properties
    
}

You can see the @ ConfigurationProperties annotation previously used in YAML configuration. This annotation indicates that the properties in this class will correspond to the properties prefixed with server in the configuration file! In other words, the attributes in this class are the attributes that we can configure with the server prefix in the configuration file!

You can know which configurations can be made in the configuration file by viewing the properties in the property class (ServerProperties) corresponding to the configuration class (HttpEncodingAutoConfiguration) and the bound prefix (prefix = "server"); If it is not configured, the attribute class will adopt the default value, and the Convention is greater than the configuration!

3. Summary

Summary of SpringBoot auto configuration process:

  1. SpringBoot will load a large number of candidate configuration classes (xxxAutoConfiguration) at startup;
  2. Judge whether a configuration class will take effect according to the current scene conditions (@ ConditionalOn...)!
  3. If the configuration class takes effect, the configuration class will add components to the container;
  4. The Properties of these components will be obtained from the corresponding Properties class (xxxProperties);
  5. All configurations that can be made in the configuration file are Properties of the Properties class;
  6. By referring to the Properties of the Properties class, you can know what can be configured in the configuration file!

The research on the principle is almost here. We still have to learn how to use it 😪!

Posted by frewuill on Sun, 19 Sep 2021 10:57:52 -0700