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.