Be serious about writing, not clickbait. Wechat search: program ape Arang.

The article is available at Github.com/niumoo/Java… And program ape Alang’s blog, point attention, don’t get lost.

Note: This Spring Boot series of articles is based on Spring Boot version V2.1.1.release, which may vary slightly.

preface

Complete configuration examples and explanations are provided on the Spring Boot official website.

It can be said that one of the essence of Spring Boot is automatic configuration. It saves a lot of configuration time for development and can be integrated into the development of business logic faster. Then how to achieve automatic configuration?

1. @SpringBootApplication

Follow SpringBoot’s bootclass annotation @SpringBootApplication for source tracing to find the principle of automatic configuration.

@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

@enableAutoConfiguration Enables automatic configuration.

@ComponentScan Turns on annotation scanning

As you can see from SpringBootApplication, this is a simple annotation configuration that includes auto-configuration, configuration classes, package scanning, and more.

2. @EnableAutoConfiguration

To follow up, check out the @enableAutoConfiguration source code. The most important one is @import, which imports a class that translates to an auto-configuration selector. This class is essentially an auto-configured load selector.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<? >[] exclude()default {};

    String[] excludeName() default {};
}

Copy the code

Continue to follow AutoConfigurationImportSelector. Class. In this class getCandidateConfigurations there is one important method. Automatic configuration classes for loading Spring Boot configurations.

GetAutoConfigurationEntry picking effective automatic configuration class.

protected AutoConfigurationEntry getAutoConfigurationEntry( AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
		if(! isEnabled(annotationMetadata)) {return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata,
				attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = filter(configurations, autoConfigurationMetadata);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}	

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
				getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
		Assert.notEmpty(configurations,
				"No auto configuration classes found in META-INF/spring.factories. If you "
						+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}
Copy the code

The following is the result of filtering in DEBUG mode. Since I only added the Web module, only the Web-related automatic configuration is available.

3. XxxAutoConfiguration xxxProperties

AutoConfiguration = AutoConfiguration = AutoConfiguration = AutoConfiguration = AutoConfiguration = AutoConfiguration

Chose ServletWebServerFactoryAutoConfiguration here.

@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
// Determine if the current project has this class
/ / CharacterEncodingFilter; Filter for garble resolution in SpringMVC;
@ConditionalOnClass(ServletRequest.class)
//Spring underlying @Conditional annotations (Spring annotations), depending on different conditions, if
// If the specified condition is met, the configuration in the entire configuration class will take effect; Check whether the current application is a Web application. If yes, the current configuration takes effect
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
Copy the code

It is important to note the @ EnableConfigurationProperties (ServerProperties. Class). This means enabling the ConfigurationProperties function for the specified class; Bind the corresponding values in the configuration file to ServerProperties; Add ServerProperties to the IOC container.

Take a look at ServerProperties.

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

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

Obviously, we use the ConfigurationProperties binding property to map properties starting with the Server in the file. Combined with default configuration

# / meta-inf /spring-configuration-metadata.json {"name": "server.port", "type": "java.lang.Integer", "description": "Server HTTP port.", "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties", "defaultValue": 8080 }Copy the code

Achieve the purpose of automatic configuration.

4. Automatic configuration summary

  1. When SpringBoot starts, the main configuration class is loaded and the automatic configuration @enableAutoConfiguration is enabled.
  2. @enableAutoConfiguration imports the auto-configuration classes defined in meta-INF/Spring. factories into the container.
  3. Filter valid auto-configuration classes.
  4. Each automatic configuration class is combined with the corresponding xxxproperties.java to read configuration files for automatic configuration.

5. The configuration class

Automatic configuration saves us a lot of configuration file writing, so do we need to write XML when we customize the configuration? Spring Boot can be configured using the SpringApplicationXML file, but we usually use the @Configuration class instead, which is officially recommended.

5.1 the XML configuration

Define the helloService Bean.


      
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="helloService" class="net.codingme.boot.service.HelloService"></bean>

</beans>
Copy the code

Importing configuration.

@ImportResource(value = "classpath:spring-service.xml")
@SpringBootApplication
public class BootApplication {

    public static void main(String[] args) { SpringApplication.run(BootApplication.class, args); }}Copy the code

5.2 Annotation Configuration

This method is equivalent to the above XML configuration and is officially recommended. Classes annotated by @Configuration (to be in the package path scanned) will be scanned.

/** * <p> * Configuration class, equivalent to the configuration of XML -> beans in traditional Spring development **@Author niujinpeng
 * @Date2018/12/7 0:04 * /
@Configuration
public class ServiceConfig {

    The default ID added to the container is the method name (helloService) **@return* /
    @Bean
    public HelloService helloService(a) {
        return newHelloService(); }}Copy the code

6. The appendix

@Conditional extends annotations Function (Determine whether the current specified condition is met)
@ConditionalOnJava Check whether the Java version of the system meets requirements
@ConditionalOnBean The specified Bean exists in the container.
@ConditionalOnMissingBean There is no specified Bean in the container;
@ConditionalOnExpression Satisfies the SpEL expression specification
@ConditionalOnClass There are specified classes in the system
@ConditionalOnMissingClass There is no specified class in the system
@ConditionalOnSingleCandidate There is only one specified Bean in the container, or the Bean is the preferred Bean
@ConditionalOnProperty Whether a specified property in the system has a specified value
@ConditionalOnResource Whether the specified resource file exists in the classpath
@ConditionalOnWebApplication The current environment is web
@ConditionalOnNotWebApplication The current environment is not Web
@ConditionalOnJndi JNDI has the specified entry

The article code has been uploaded to GitHub Spring Boot for automatic configuration.

After < >

Hello world 🙂

I am a lang, lang of the moon, a technical tool person who moves bricks every day. Personal website: www.wdbyte.com If you want to subscribe, you can follow the public account of “Procedural Ape Alang”, or the blog of procedural ape Alang, or add me on wechat (WN8398).

This article has also been compiled at GitHub.com/niumoo/Java… Welcome Star.