Home  >  Article  >  Java  >  What is the implementation principle of SpringBoot automatic configuration?

What is the implementation principle of SpringBoot automatic configuration?

WBOY
WBOYforward
2023-05-15 15:58:065110browse

1. What is springboot automatic configuration

SpringBoot turns on automatic configuration through the @EnableAutoConfiguration annotation and scans the spring.factories file under the jar package. This file contains classes that can be automatically configured. When the conditions specified by the @Condition annotation are met, it will be instantiated with the support of dependencies and registered in the Spring container.

Generally speaking, when we wrote the ssm project before, we configured a large number of coordinates and configuration content. The process of setting up the environment took up a lot of time in the project development. The biggest feature of SpringBoot is that it simplifies various xml configuration content, so springboot's automatic configuration uses annotations to make default configurations for some conventional configurations, simplifying the xml configuration content so that your project can run quickly.

Springboot core configuration principle:

  • Auto-configuration classes are stored in org.springframework.boot.autoconfigure under spring-boot-autoconfigure-version number.jar

  • Start the container when we configure debug=true in application.properties. You can see the initial configuration of server initialization

  • DispatcherServletAutoConfigratioRegister front-end controller

  • EmbeddedServletContainerAutoConfigurationRegister container type

  • HttpMessageConvertersAutoConfiguration registers json or xml processor

  • JacksonAutoConfiguration registers json object parser

  • If you add dependencies on other functions, springBoot will also Implement automatic configuration of these functions

What is the implementation principle of SpringBoot automatic configuration?

2. Starter component

Starter component is a Maven dependency that can be loaded in the application item. Only by adding the corresponding dependency configuration in the Maven configuration can you use the corresponding Starter component. For example, adding the spring-boot-starter-web dependency can be used to build a REST API service, which includes Spring MVC and Tomcat embedded containers.

A complete Starter component includes the following two points:

  • An automatic configuration module that provides automatic configuration function

  • Provides dependencies The component module of the relationship management post function encapsulates all the functions of the component and can be used out of the box.

spring-boot-starter-web depends on the source code

package org.springframework.boot.autoconfigure.web.servlet;
@Configuration
@ConditionalOnClass({ServletRequest.class})
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class})
public class ServletWebServerFactoryAutoConfiguration {
    ......
}
@

3. Three major annotations

@SpringBootConfiguration: Inherited from Configuration, supports JavaConfig method to configure.

@EnableAutoConfiguration: This article focuses on explaining, mainly used to enable automatic configuration.

@ComponentScan: Automatically scan components. By default, all classes with specified annotations under the package and sub-packages of the class are scanned, and they are automatically assembled into the bean container. The annotations that will be automatically assembled include @Controller , @Service, @Component, @Repository, etc. Scan paths can also be specified.

4. @EnableAutoConfiguration

This annotation helps us automatically load the default configuration. It has two key annotations @AutoConfigurationPackage and @Import. Let’s learn more about the @Import annotation.

@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		//检查自动配置功能是否开启,默认开启
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		//加载自动配置的元信息
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		//获取候选配置类
		List<String> configurations = getCandidateConfigurations(annotationMetadata,
				attributes);
		//去掉重复的配置类
		configurations = removeDuplicates(configurations);
		//获得注解中被exclude和excludeName排除的类的集合
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		//检查被排除类是否可实例化、是否被自动注册配置所使用,不符合条件则抛出异常
		checkExcludedClasses(configurations, exclusions);
		//从候选配置类中去除掉被排除的类
		configurations.removeAll(exclusions);
		//过滤
		configurations = filter(configurations, autoConfigurationMetadata);
		//将配置类和排除类通过事件传入到监听器中
		fireAutoConfigurationImportEvents(configurations, exclusions);
		//最终返回符合条件的自动配置类的全限定名数组
		return StringUtils.toStringArray(configurations);

@Import(AutoConfigurationImportSelector.class) annotation, import the AutoConfigurationImportSelector class here. There is a very important method in this class - selectImports(), which covers almost all processing logic of component automatic assembly, including obtaining candidate configuration classes, deduplicating configuration classes, excluding unnecessary configuration classes, filtering, etc. Finally, an array of fully qualified names of qualified auto-configuration classes is returned.

5. SpringFactoriesLoader

The SpringFactoriesLoader class is defined in the spring-core package. This class implements the function of retrieving the META-INF/spring.factories file and obtaining the configuration of the specified interface. Two external methods are defined in this class:

  • loadFactories obtains the instance of its implementation class based on the interface class. This method returns a list of objects.

  • loadFactoryNames gets the name of its interface class based on the interface. This method returns a list of class names.

The key to the above two methods is to obtain the spring.factories file from the specified ClassLoader and parse it to get the class name list. The specific code is as follows:

public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    try {
        Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
        List<String> result = new ArrayList<String>();
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
            String factoryClassNames = properties.getProperty(factoryClassName);
            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
        }
        return result;
    }
    catch (IOException ex) {
        throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
                "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
    }
}

It can be seen from the code that in this method, the spring.factories files under all jar packages in the entire ClassLoader will be traversed. In other words, we can configure the spring.factories file in our own jar without affecting the configuration in other places or being overwritten by other people's configuration.

spring.factories are obtained through Properties analysis, so the content in the file we write is configured in the following way:

com.xxx.interface= com.xxx.classname

The above is the detailed content of What is the implementation principle of SpringBoot automatic configuration?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete