Spring Boot auto configuration source code analysis

Keywords: Java Spring Spring Boot

catalogue

 

  • preface

  • Source version

  • @What did SpringBootApplication do?

  • @What did EnableAutoConfiguration do?

  • summary

preface

Why is Spring Boot so popular? Because it's convenient, it's out of the box, but have you ever thought about why it's so convenient? The traditional SSM architecture configuration file needs to be written for at least half a day. After using Spring Boot, you only need to introduce a starter to use it directly. Why???

The reason is very simple. Work has been done inside each starter. For example, the starter of Mybatis has built-in available SqlSessionFactory by default.

As for how to build it? Spring Boot   How to make it effective? This article introduces the automatic configuration principle of spring boot from the perspective of source code.

Source version

The author Spring Boot is based on 2.4.0. There are some changes in each version. Readers try to keep consistent with me to prevent some differences in the source code.

@What did SpringBootApplication do?

Let's put it this way, the annotation did nothing, and the waste and work were handed over to the subordinates. The source code is as follows:

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

Three important notes are marked above, as follows:

  1. @SpringBootConfiguration: it is actually @ Configuration, so the main startup class can be used as a Configuration class, such as Bean injection.

  2. @Enable autoconfiguration: if this annotation is approved, the name will be different. Enable autoconfiguration. Oh, the key is here

  3. @ComponentScan: package scan annotation.

After the above analysis, an annotation @ EnableAutoConfiguration is finally positioned. As the name suggests, it must be related to automatic configuration, which should be analyzed emphatically.

@What did EnableAutoConfiguration do?

If you want to know what you have done, you must look at the source code, as follows:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}

Two important notes are marked above, as follows:

  1. @AutoConfigurationPackage: auto configuration package annotation. By default, all components in the package where the main configuration class (@ SpringBootApplication) is located and its sub packages are scanned into the IOC container.

  2. @Import: there is no need to say more about this annotation. It has been mentioned many times in the previous article. Here, AutoConfigurationImportSelector is imported to inject autoconfiguration classes.

The above is just a simple analysis of the two annotations, which will be introduced in detail from the source code below.

@AutoConfigurationPackage

What does this annotation do? This needs to look at the source code, as follows;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {}

The important thing is the @ Import annotation, which imports AutoConfigurationPackages.Registrar. What does this class do? The source code is as follows:

In fact, there are only two methods, but the most important one is the registerBeanDefinitions method. However, this method must be injected into beans. The focus here is on which beans to inject. The key source code is as follows:

//Get scanned packages
new PackageImports(metadata).getPackageNames().toArray(new String[0])

Follow up the code. The main logic is in #PackageImports.PackageImports(). The source code analysis is shown in the following figure:

From the above source code analysis, we can see that the package name scanned here consists of two parts, as follows:

  1. Package name resolved from two attributes in the @ AutoConfigurationPackage annotation.

  2. Annotate the package name of AutoConfigurationPackage, that is, the package name of @ SpringBootApplication.

@By default, AutoConfigurationPackage scans the package where the main configuration class (@ SpringBootApplication) is located and all components in its sub packages into the IOC container.

@Import(AutoConfigurationImportSelector.class)

Needless to say, the most important annotation is AutoConfigurationImportSelector. Let's take a look at its inheritance relationship, as shown in the following figure:

The inheritance relationship of this class is quite simple. It implements some necessary components of xxAware injection in Spring, but the most important thing is to implement an interface of DeferredImportSelector, which extends ImportSelector and changes its operation mode, which will be introduced in later chapters.

"Note": this class will lead to a misunderstanding. I usually see that xxxSelector has a reflection arc. I will definitely DEBUG on the selectImports() method, but this class does not execute this method at all. I am a little skeptical about life for the first time. It turns out that it uses the interface method of DeferredImportSelector.

In fact, the method that this class really implements logic is the process() method, but the main task of loading the automatic configuration class is entrusted to the getAutoConfigurationEntry() method. The specific logic is shown in the following figure:

The logic in the figure above is very simple. First get the auto configuration class from the spring.factories file and remove the excluded auto configuration class defined in @ SpringBootApplication.

Step ④ in the figure above is to load the automatic configuration class from META-INF/spring.factories. The code is very simple. When analyzing and starting the process in the previous article, many components were loaded from the spring.factories file, and the code is similar.

Many automatic configuration classes are built in the spring.factors file in springboot autoconfigure, as follows:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
................

Learned about Spring Boot   How to load an auto configuration class is also very easy to customize an auto configuration class. The subsequent chapters teach you how to customize your own auto configuration class. There are still many ways

summary

This paper analyzes how the automatic configuration of Spring Boot is loaded from the perspective of source code. In fact, the analysis is very simple. I hope the author's article can help you have a deeper understanding of Spring Boot.

Posted by hobojjr on Wed, 17 Nov 2021 17:51:14 -0800