This is my first day to participate in the More text challenge. For details, see more text Challenge
preface
The SpringFactoriesLoader factory loading mechanism is a custom loading mechanism provided by Spring internally, similar to the Java SPI, and requires only the meta-INF /spring.factories of a module. The key in the Properties format file is the full name of the interface, annotation, or abstract class, and the value is a comma, “, “separated implementation class. Use the SpringFactoriesLoader to implement the corresponding implementation class into the Spirng container.
The SpringFactoriesLoader is described with the implementation of @enableAutoConfiguration (SpringBoot 2.0.x) for SpirngBoot.As you can see, this configuration satisfies the SpringFactoriesLoader requirements, so let’s see how to trigger it to find the appropriate class and load it.You can see the @enableAutoConfiguration annotation in the SpringBootApplication;Can see the annotations, @ Import (AutoConfigurationImportSelector. Class) the annotation will AutoConfigurationImportSelector instantiated and injected into the container. AutoConfigurationImportSelector selectImports methods
Core code for the selectImports method
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
Copy the code
To go over the getAutoConfigurationEntry method:
The core code of getAutoConfigurationEntry method
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
Copy the code
GetCandidateConfigurations method below:
SpringFactoriesLoader (SpringFactoriesLoader) SpringFactoriesLoader (SpringFactoriesLoader)
List configurations =SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
Copy the code
GetSpringFactoriesLoaderFactoryClass () returns the EnableAutoConfiguration. Class;
SpringFactoriesLoader. LoadFactoryNames () method:
FACTORIES_RESOURCE_LOCATION = “meta-INF /spring.factories”;
If you have a meta-INF /spring.factories under the handy JAR, you can filter the corresponding key values. Here the key value of using org. Springframework. Boot. Autoconfigure. EnableAutoConfiguration.
This gives us a set of @Configuration classes, which we can instantiate via reflection and inject into the IOC container. The container then has a set of Configuration classes labeled @Configuration in the JavaConfig form.
For example, to load a Tomcat container, the spring.factories configuration file at the beginning of this article has the following configuration classes with the key EnableAutoConfiguration:
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
Copy the code
EmbeddedWebServerFactoryCustomizerAutoConfiguration class:
/**
* Nested configuration if Tomcat is being used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
public static class TomcatWebServerFactoryCustomizerConfiguration {
@Bean
public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment,
ServerProperties serverProperties) {
return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
}
}
/**
* Nested configuration if Jetty is being used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class })
public static class JettyWebServerFactoryCustomizerConfiguration {
@Bean
public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment,
ServerProperties serverProperties) {
return new JettyWebServerFactoryCustomizer(environment, serverProperties);
}
}
/**
* Nested configuration if Undertow is being used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Undertow.class, SslClientAuthMode.class })
public static class UndertowWebServerFactoryCustomizerConfiguration {
@Bean
public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment,
ServerProperties serverProperties) {
return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
}
}
/**
* Nested configuration if Netty is being used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HttpServer.class)
public static class NettyWebServerFactoryCustomizerConfiguration {
@Bean
public NettyWebServerFactoryCustomizer nettyWebServerFactoryCustomizer(Environment environment,
ServerProperties serverProperties) {
return new NettyWebServerFactoryCustomizer(environment, serverProperties);
}
}
Copy the code
You can see in this configuration class that there are four types of Web containers supported for SpringBoot2.0, depending on whether they depend on the corresponding container implementation class (@ConditionalonClass control implementation).
The default in SpringBoot is to use Tomcat as the Web container (SpringBoot2.0.x) because
This dependency imports the Tomcat JAR package by default.
A large number of Spring-boot-starter components are developed in SpringBoot, which depend on corresponding implementation packages.
conclusion
SpringFactoriesLoader: configures the value class in the spring.fatories configuration file. The corresponding bean is then instantiated selectively (@ConditionalonClass) via Spring’s @Configuration.