Make writing a habit together! This is my first day to participate in the “Gold Digging Day New Plan · April More text challenge”, click to see the details of the activity.

What is auto-assembly

When SpringBoot is used, beans are automatically assembled into the IoC container. The automatic assembly process is as follows:

  • Get the spring.factories file in the meta-INF folder of the component
  • The spring.factories file lists the classes that need to be injected into the IoC container
  • Inject the entity class into the IoC container for use

Principle of automatic assembly

To analyze the process, start by looking at the code for the startup class:

@SpringBootApplication
public class CompanyProjectApplication {
      public static void main(String[] args) {
        SpringApplication.run(RuoYiApplication.class, args);
    }
Copy the code

@SpringBootApplication

You can see that the main part is the @SpringBootApplication annotation, and if we go into the annotation class, we can see that the @SpringBootApplication annotation is actually a composite annotation

@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 {
    ...
}
Copy the code

@target ({elementtype.type}) // Indicates the position of the annotation to be decorated.TYPE indicates that only classes can be decorated

@retention (retentionPolicy.runtime) // Indicates the scope of annotations

Documented // This annotation will be Documented in the API

@inherited // Indicates the inheritance of annotations

@SpringBootConfiguration This annotation is essentially the @Configuration annotation.

@ComponentScan annotation, which specifies the path to be scanned. If no specific path is specified, the path to be scanned is the package of the currently decorated class and its subpackages.

That leaves @enableAutoConfiguration, which is the key to SpringBoot autoassembly.

@EnableAutoConfiguration

Enter @ EnableAutoConfiguration annotations, you can see the @ AutoConfigurationPackage and @ Import ({AutoConfigurationImportSelector. Class})

@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<? >[] exclude() default {}; String[] excludeName() default {}; }Copy the code

The package to which the class to which the annotation is added is managed as an auto-configuration package through the @AutoConfigurationPackage annotation.

Is the most important thing and @ EnableAutoConfiguration annotation AutoConfigurationImportSelector. Class, class will need to assembly assembly to the IoC container, the following key analyze the implementation of this class

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }
Copy the code

Into the AutoConfigurationImportSelector class, according to the breakpoint debug, enter getAutoConfigurationEntry method, GetCandidateConfigurations calls to the method, called the SpringFactoriesLoader loadFactoryNames, through the debug can see loading in the meta-inf/spring. Factories files

configurations = this.filter(configurations, autoConfigurationMetadata); Call the following method private List<String> filter(List<String> Configurations, AutoConfigurationMetadata autoConfigurationMetadata) { long startTime = System.nanoTime(); String[] candidates = StringUtils.toStringArray(configurations); boolean[] skip = new boolean[candidates.length]; boolean skipped = false; Iterator var8 = this.getAutoConfigurationImportFilters().iterator(); while(var8.hasNext()) { AutoConfigurationImportFilter filter = (AutoConfigurationImportFilter)var8.next(); this.invokeAwareMethods(filter); boolean[] match = filter.match(candidates, autoConfigurationMetadata); for(int i = 0; i < match.length; ++i) { if (! match[i]) { skip[i] = true; candidates[i] = null; skipped = true; } } } if (! skipped) { return configurations; } else { List<String> result = new ArrayList(candidates.length); int numberFiltered; for(numberFiltered = 0; numberFiltered < candidates.length; ++numberFiltered) { if (! skip[numberFiltered]) { result.add(candidates[numberFiltered]); } } if (logger.isTraceEnabled()) { numberFiltered = configurations.size() - result.size(); logger.trace("Filtered " + numberFiltered + " auto configuration class in " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms"); } return new ArrayList(result); }}Copy the code

You can see the match method match. AutoConfigurationMetadata, load is the nature of the meta-inf/spring – autoconfigure – metadata. The properties of the contents of the file. After filtering, only 46 files remain

conclusion

In fact, we have introduced the principle of SpringBoot automatic assembly. I found a summarized flow chart on the Internet as follows:

Well, this article will give you an introduction here, feel helpful, leave a thumbs-up or comment again go! Thanks ~ 💐