SpringBoot Auto-assembly Principle Analysis - Interview can answer this question

1. Preface

SpringBoot is the most mainstream framework in current software. It has its own image in both job and interview. SpringBoot mainly solves the heavy xml configuration Bean of traditional spring and realizes automatic assembly. So we've often been asked in interviews how SpringBoot automates assembly.

This article will analyze the principles of automatic assembly from springboot source and summarize how interviews are concise

2. Source Code Parsing

We parsed it in springboot version 2.2.5.RELEASE

2.1 @SpringBootApplication Source Parsing

First look at the springboot startup comment @SpringBootApplication

@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 {

	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};

	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};

	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;

}

You can see that the @SpringBootApplication is made up of three annotations, @ComponentScan annotation is the spring native annotation, which scans the package of the boot class and all the Bean components of the subpackage and registers them in the IOC container. Two more we'll look at the source code

@SpringBootConfiguration source:

@EnableAutoConfiguration source:

Summary @SpringBootApplication annotations are assembled automatically by three annotations, each of which serves as follows

  • @SpringBootConfiguration: Mark startup class as a spring configuration class
  • @EnableAutoConfiguration: Core Notes for Auto-assembly (EnableAutoConfiguration)
  • @ComponentScan: Scan the package where the boot class is located and all components marked as Bean s under the subpackage and register them in the IOC container

2.2 @EnableAutoConfiguration Source Parsing

The @EnableAutoConfiguration annotation is the core annotation for auto-assembly. See above that his source code is importing the AutoConfiguration ImportSelector class through the @Import annotation. Let's take a look at the AutoConfiguration ImportSelector source code:

From the source code, AutoConfigurationImportSelector is a word class of ImportSelector. One of the great uses of the @Import annotation is to import an ImportSelector class and return an array collection of the full names of all classes that need to be registered as bean s using the selectImports method, as shown in our previous article. Detailed @Import comment

Let's look again at the selectImports method of the AutoConfigurationImportSelector class

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
	// Determine if the automatic assembly switch is on
	if (!isEnabled(annotationMetadata)) {
		return NO_IMPORTS;
	}
	AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
			.loadMetadata(this.beanClassLoader);
	AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
			annotationMetadata);
	return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

First, the isEnabled method is used to determine whether the automatic assembly switch is on or not. We will not go into details here. Let's start with the next two steps.

2.2.1. AutoConfiguration MetadataLoader.loadMetadata() Method Source Analysis:

loadMetadata() method source:


  • META-INF/spring-autoconfigure-metadata.properties file content properties:


  • LoadeProperties method source for PropertiesLoaderUtils:


  • AutoConfiguration Metadata object that was last created and returned

Taken together, the AutoConfiguration MetadataLoader.loadMetadata() method is used to read from the spring-boot-autoconfigure dependency
The contents of the spring-autoconfigure-metadata.properties configuration file are encapsulated as an AutoConfiguration Metadata object

2.2.2 getAutoConfiguration Entry Method Source Code Analysis (Key)

// GetAutoConfiguration Entry Method Source
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
		// Judge again if the auto-assembly switch is on
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		// Gets the exclude and excludeName properties of the @EnableAutoConfiguration comment
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		// Get the contents of the spring.factories configuration file under this dependency
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		// Remove duplicate data
		configurations = removeDuplicates(configurations);
		// Gets the contents of the spring.autoconfigure.exclude configuration file and merges it into a collection with the exclude and excludeName properties
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		// Verify what needs to be excluded from configurations
		checkExcludedClasses(configurations, exclusions);
		// Remove what needs to be excluded from configurations
		configurations.removeAll(exclusions);
		// Filter again the content in configurations
		configurations = filter(configurations, autoConfigurationMetadata);
		// Turn off auto-assembly events in the spring listener
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

The isEnabled method is still used to determine whether the auto-assembly switch is on or not, so let's not go into details here. Let's start with the later analysis.

  • The getAttributes method is to get the exclude and excludeName attributes of the @EnableAutoConfiguration annotation, which are not set by default by the startup class and are no longer analyzed in depth here


  • getCandidateConfigurations method source analysis (emphasis):

    1. SpringFactoriesLoader.loadFactoryNames method source code:

2. spring.factories configuration file

3. Result ultimately returned by the getCandidateConfigurations method


  • removeDuplicates(configurations): literally remove duplicate elements

  • getExclusions Source Analysis:This action binds the exclude and excludeName property contents to the environment variable, which are skipped because they are empty by default

  • checkExcludedClasses(configurations, exclusions): The method name tells you what the method checks for in the configurations content to exclude. Since exclusions defaults to empty, there is nothing effective to do here, so no further scoring is needed

  • configurations.removeAll(exclusions): You can see from the method name that you want to remove elements that need to be excluded

  • Filter (configurations, autoConfiguration Metadata) method source analysis (emphasis):

  • FireAutoConfiguration ImportEvents (configurations, exclusions): Turn off automatic assembly events in the spring listener

  • New AutoConfiguration Entry (configurations, exclusions): Final result returned

Combining the above @EnableAutoConfiguration annotations, import the subclass AutoConfigurationImportSelector of ImportSelector through the @Import annotation, which loads and reads the contents of the spring-autoconfigure-metadata.properties configuration file and the spring.factories configuration file under all spring-boot-autoconfigure dependencies through the selectImports method. Component elements that need to be filtered from the spring.factories file are filtered according to the filtering rules of the AutoConfigurationImportFilter filter under the AutoConfigurationImportSelector class and the contents of the spring-autoconfigure-metadata.properties configuration file (Of course, there was one more step before that to filter the contents of the spring.factories configuration file based on the exclude and excludeName properties of the @EnableAutoConfiguration annotation, which are empty by default, so nothing has been done in this step) , eventually returns an array of class full names for the remaining components in the spring.factories file, and is registered as a Bean by the IOC container

Keywords: Java JavaEE

Added by midge1970 on Mon, 29 Nov 2021 03:04:28 +0200