Spring Boot Autoconfiguration, as the name suggests, is intended to be self-configurable, freeing us from configuration misery. So, to automate configuration, it needs to solve three problems:

1. What conditions are met? 2. Which beans are created? 3. What properties does the bean created have? Here’s an example: When we create a Springboot project, introducing the spring-boot-starter-web dependency will automatically create a Port 8080 tomcat for us and configure the project’s custom port (server.port) through the configuration file application.yaml.

A brief explanation: 1. What kind of conditions? Because we introduced the spring-boot-starter-Web dependency. 2. Which beans were created? An embedded Tomcat is created and started. What are the properties of the bean you created? A custom port (server.port) is configured with application.yaml.

Springboot source code in a class that EmbeddedWebServerFactoryCustomizerAutoConfiguration download the source code to the cloud (a batch of fast)





<1.1> adds the @Configuration annotation to the class to declare it to be a Configuration class. Since it is intended for automatic configuration, the class name is suffixed with AutoConfiguration. <1.2> is the configuration class used to initialize Tomcat.

Thus, we can conclude that the problem of “which beans to create” can be solved with the Configuration class annotated by @Configuration.

< 2.1 > the @ ConditionalOnWebApplication condition is added to the class notes, said the current configuration class needs to under the condition of the current project is Web project, to take effect. In a SpringBoot project, the project types are divided into Web projects (using SpringMVC or WebFlux) and non-Web projects. So we can easy to understand, why EmbeddedWebServerFactoryCustomizerAutoConfiguration configuration class will require the project type is Web project, only the Web project it is necessary to create an embedded Web server.

ConditionalOnClass specifies that the current configuration class is valid only if the current project has a specified class. (The line below figure 1.2).

In this way, we can get the second conclusion. Through conditional annotations, we can solve the question “What conditions are met?” The problem.

< > 3.1, using the @ EnableConfigurationProperties annotations, let ServerProperties configuration attribute class to take effect. The @configurationproperties annotation is defined in SpringBoot to declare the ConfigurationProperties class, into which configuration items with the specified prefix are batch injected.

< 3.2 >, when creating TomcatWebServerFactoryCustomizer objects, will ServerProperties into the among them, as a follow-up to create Web server configuration. That is, we can customize the configuration of the Web server by modifying the configuration items in the configuration file.

Thus, we can conclude that by configuring properties, we can solve the problem of “properties of Bean created?” The problem.

So far we have a fairly clear understanding of how SpringBoot solves the three problems we mentioned above, but it still doesn’t work automatically. For example, spring-boot-starter-Web, which we introduced, relies on SpringBoot to know which configuration classes to scan.

After we pass the SpringApplication#run(Class<? > primarySource, String… The SpringFactoriesLoader class reads the Spring. factories file in the meta-INF directory. Get the configuration classes defined by each framework that need to be configured automatically.

Thus, the Configuration class that was annotated with @Configuration is upgraded to the class auto-configuration class. In this way, SpringBoot can automatically create the corresponding Bean after obtaining the configuration class that needs to be configured automatically.

The Spring Boot convention reads application.yaml, application.properties and other configuration files, so as to realize the custom property configuration of the Bean. You can even cancel the Bean creation with the @conditionalonProperty annotation.

Custom starter implementation

Start a project and create two modules on both sides

The module1 is used to provide the starter, and the Module2 is used to use the starter. (The last printed port number to see if we reference it successfully)

This is the configured property class, which reads the properties prefixed with lmD. server in application.properties (note that the application.properties is your module2 configuration file).

The following configures the autowire class

Then introduce module1’s dependencies in module2’s POM.xml file.

Then define the properties in Module2’s application.properties (we set the port to 8011).

As a final step, run module2’s startup class directly.

Finally, we successfully referenced the custom starter.

Note: POM files for Module1

4.0.0 com.example Demo 0.0.1-SNAPSHOT Demo Project for Spring Boot

< properties > < Java version > 1.8 < / Java version > < project. Build. SourceEncoding > utf-8 < / project. Build. SourceEncoding > <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> < spring - the boot version > 2.3.0. RELEASE < / spring - the boot. Version > < / properties > < dependencies > <! <dependency> <groupId>org.springframework. Boot </groupId> The < artifactId > spring - the boot - starter < / artifactId > < version > 2.1.8. RELEASE < / version > < / dependency > < / dependencies >Copy the code

Pom files for Module2

4.0.0 com. Springboot Stater 0.0.1-SNAPSHOT Stater Demo project for Spring Boot

< properties > < Java version > 1.8 < / Java version > < project. Build. SourceEncoding > utf-8 < / project. Build. SourceEncoding > <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <dependency> < the groupId > com. Example < / groupId > < artifactId > demo < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > < / dependency > </dependencies>Copy the code