The introduction

Recently, a reader was asked this question in an interview: “Springboot is used in your project. How does springboot auto-configuration work?” This should be one of the most common interview questions in Springboot. Let’s take this problem together with the anatomy of springBoot automatic configuration principle.

SpringMvc vs. SpringBoot

First of all, let’s go back and build aspringmvcthehello-wordthewebProject (xmlAre we going to be inpomImport a variety of dependencies, and then each dependency may also exist version conflicts need to be eliminated. When you’ve gone through the trouble of solving dependencies, then you need to writeWeb.xml, for springmvc. XMLConfiguration files. We just want to writeHello - wordIt’s just a project, and a lot of time is spent on configuration files andjarPackage dependencies above. Greatly affected the efficiency of our development, as well as increasedwebDifficulty of development. To simplify this complex configuration and the conflicting dependencies between versions,springBootThat’s what happened. We are now passing throughideaTo create aspringbootProjects are solved in minutes and you don’t have to worry about configuration (basically zero configuration). Let you really implement out of the box.SpringBootHelp you save a lot of time to spend with your girlfriend, not a programmer how can have a girlfriend? (You can have a new one if you don’t have oneIt not only allows you to spend more time developing your business logic, but also significantly reduces itwebThe threshold of development. soSpringBootOr more understanding of people’s clothes, wrong wrong is understanding, know where the pain point of developers.

SpringBoot automatically loads the configuration

sinceSpringbootAs useful as it is, as a user, we are curious to see how it works out of the box.Spring BootThere is a global configuration file:Application. The properties and application. Yml. In this global file you can configure all kinds of parameters such as you want to change the portserver.portOr if you want to adjust the log level, you can configure it all. See the official website for more configurable properties.Docs. Spring. IO/spring – the boot… So many attributes, how do these attributes work in the project?SpringBootThe project appears to have no configuration, configuration “(Application. The properties and application. YmlExcept), even if the configuration above can not find a breakthrough, then we can only find the entry from the boot class above. The startup class is just a bare onemainMethod, which has only one note above the classSpringBootApplicationThe note isSpring BootEssential notes for the project. The principle of auto-configuration must have a lot to do with this annotation! Let’s take a look at this annotation.@ SpringBootApplication annotations

@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

There is nothing to say about the top four annotations here. Basically, if you have implemented custom annotations, you know what they mean.

  • @SpringBootConfigurationInherited from@Configuration, the two functions are the same, marking the current class is a configuration class.
  • @ComponentScanUsed on classes or interfaces to specify scan paths, and in Xml<context:component-scan base-package="" />Same configuration.springbootIf you do not write the scan path, the default is to start the class path.
  • @EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
Copy the code

Let’s focus on this noteAutoConfigurationImportSelectorThis classgetCandidateConfigurationsThis method goes throughSpringFactoriesLoader.loadFactoryNames()Scan all withMETA-INF/spring.factoriesthejar(Spring. FactoriesSpring BootTheir ownSPIMechanism).spring-boot-autoconfigure-x.x.x.x.jarThere is a spring.factories file in.spring.factoriesFiles come in groupsKey = valueForm one of themkeyIs the full class name of the EnableAutoConfiguration class, and its value is aAutoConfigurationAt the end of the list of class names, there areRedis, mqThe class names are separated by commas.

We’re going back togetAutoConfigurationEntryWhen this method is executedgetCandidateConfigurationsWhen we do this method we can see that the total load at this point127Automatic configuration classes.Do all of these classes have to be loaded?springbootIt’s not so silly, it advocates loading on demand.

  • It gets rid of duplicate classes
  • Filtered out our configurationexcludeThe following configuration of the annotated class is filtered outRestTemplateAutoConfigurationThis class

  • After the above processing, the remaining auto-configured classes need to meet certain conditions if they are to work. If these conditions are metspring bootThis is done through conditional annotations.

ConditionalOnBean: when the container contains the specified Bean

@ ConditionalOnClass: when the classpath has under the condition of the specified class @ ConditionalOnExpression: based on SpEL expression is true as a condition of judgment when to instantiate @ ConditionalOnJava: ConditionalOnJndi: ConditionalOnMissingBean ConditionalOnMissingBean ConditionalOnMissingBean ConditionalOnJndi: ConditionalOnMissingBean ConditionalOnMissingBean ConditionalOnJndi When the container is not specified under the condition of Bean @ ConditionalOnMissingClass: when the container is not specified in the class of @ ConditionalOnWebApplication: When the current project under the condition of the Web project @ ConditionalOnNotWebApplication: under the condition of the current project is not a Web project @ ConditionalOnProperty: Specify the attributes for the specified value @ ConditionalOnResource: class path if there is a specified value @ ConditionalOnOnSingleCandidate: when specifying the Bean in the container is only one, or have more than one but specify preferred Bean

These notes are all combined@ConditionalAnnotation, only instantiate classes that need to be instantiated if a different combination of conditions is set to true, otherwise ignore filtering. When we go back to the code we can see that after the conditional filtering we only have 23 auto-configuration classes that meet the criteria. Everything else is filtered because it doesn’t meet the conditional comment.If we want to know which auto-configuration classes are filtered, why they are filtered, which classes are loaded, etc.spring bootThey kept a log for us. It was very sweet. We can adjust the level of our log todebug. Then we can see the following logThis is a partial log. There are four parts of logs:

  • Positive matches:@ConditionalIf true, the configuration class is loaded by the Spring container.
  • Negative matches: @ConditionalThe condition is false, the configuration class is not loaded by the Spring container.
  • Exclusions: We have identified classes that do not need to be loaded. For example, start the class configuration aboveRestTemplateAutoConfigurationclass
  • Unconditional classes: Auto-configured classes do not contain any class-level conditions, that is, classes are always automatically loaded.

Automatic configuration takes effect

ServletWebServerFactoryAutoConfiguration configuration class, for example, we explain how to effect in the global configuration file attributes, such as: Server port = 88, how work (of course not configuration will also have a default value, the default values from the org. Apache. Catalina. Startup. Tomcat).

// mark it as a configuration class
@Configuration(proxyBeanMethods = false)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
// Servletrequest.class takes effect only if there is a servletrequest.class
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
// Inject the @ConfigurationProperties annotation class into the Spring container Bean.
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
Copy the code

We can find EnableConfigurationProperties annotation configuration ServerProperties. Inside the class

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

	/** * Server HTTP port. */
	private Integer port;
Copy the code

There is a comment on this class: @ ConfigurationProperties, What it does is bind properties from the configuration file to the corresponding bean (that is, map our application.properties server.port to ServerProperties) In the class the port attribute) and @ EnableConfigurationProperties this annotation is already binding properties of the bean (ServerProperties) injection into the spring container (equivalent to @ Component annotation). All properties that can be configured in a configuration file are encapsulated in the xxxxPropertites class, and any properties that can be configured in a configuration file can refer to the property class corresponding to a particular function. By now you should be able to answer the question at the beginning of the article.

Spring Boot uses the @enableAutoConfiguration annotation to find and load all the auto-configuration classes in the meta-INF/Spring. factories configuration file. These AutoConfiguration classes are named after the AutoConfiguration end, which is actually a JavaConfig Spring container configuration class. It can use the class named after the Properties end to obtain the Properties configured in the global configuration file such as: Server.port, and the XxxxProperties class is bound to the corresponding properties in the global configuration file via the @ConfigurationProperties annotation.

I found a picture on the Internet and basically explained the process of automatic assembly.

conclusion

  • SpringBootStartup loads a large number of auto-configuration classes (via”SPI“), and then retains the required classes according to conditional annotations.
  • Let’s introduce a new component to see if springBoot is already provided by default.
  • SpringBootBasically realize “zero configuration”, and out of the box.

The end of the

  • As a result of their talent and learning, it is inevitable that there will be mistakes, if you found the wrong place, but also hope that the message to me pointed out, I will correct it.
  • If you think the article is good, your forwarding, sharing, appreciation, like, message is the biggest encouragement to me.
  • Thank you for reading. Welcome and thank you for your attention.

Picking apples on the shoulders of giants:

Docs. Spring. IO/spring – the boot… Blog.csdn.net/u014745069/…

Afoo. Me/posts / 2015 -…