Spring Boot defines various XxxxAutoConfiguration configuration classes internally, and pre-defined various required beans. These configuration classes will only be used in certain situations.
(1) How to import the automatic configuration class
Look at the source code to see how the automatic configuration class is introduced.
a) Application entry
@SpringBootApplication public class SpringBootDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringBootDemoApplication.class, args); } }
b) 类注解 @SpringBootApplication = @EnableAutoConfiguration + @ComponentScan + @Configuration
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { // ... } @Configuration public @interface SpringBootConfiguration { // ... }
c) Turn on the automatic configuration annotation @EnableAutoConfiguration
@AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { // ... }
d) Import the configuration class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector
In the AutoConfigurationImportSelector class, you can see
that spring-boot-autoconfigure-1.5.1.RELEASE.jar/META-INF/spring.factories is placed under SpringFactoriesLoader.loadFactoryNames().
quote
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
......
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
......
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
How are these classes loaded after the application starts?
By executing the SpringApplication.run() method, the current SpringBootDemoApplication will be passed in as the source, and the SpringApplication class will also read the settings in spring.factories and build the Context of the application.
spring-boot-1.5.1.RELEASE.jar/META-INF/spring.factories
quote
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
spring-boot-autoconfigure-1.5.1.RELEASE.jar/META-INF/spring.factories
quote
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
Correspondingly, when making war, the current SpringBootDemoApplication is also passed to ServletInitializer as source.
public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringBootDemoApplication.class); } }
Configuration classes can also be imported by themselves
@Configuration @Import({ DispatcherServletAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class, ErrorMvcAutoConfiguration.class, HttpEncodingAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, JacksonAutoConfiguration.class, MultipartAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, WebMvcAutoConfiguration.class }) @ComponentScan public class SpringBootDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringBootDemoApplication.class, args); } }
(2) For an example of the internal composition of the automatic configuration class,
see org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration
@Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class }) @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class }) public class WebMvcAutoConfiguration { @Bean @ConditionalOnMissingBean(HiddenHttpMethodFilter.class) public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() { return new OrderedHiddenHttpMethodFilter(); } // ... }
Conditional configuration Based on Spring's @Conditional, SpringBoot provides rich conditional configuration:
quote
@ConditionalOnClass : It takes effect when the class exists in the
classpath @ConditionalOnMissingClass : It takes effect when the class does not exist in the classpath @ConditionalOnBean : It takes effect
when the type of bean exists in the
DI container @ConditionalOnMissingBean : It takes effect when the type of bean does not exist in the DI container
@ConditionalOnSingleCandidate : It takes effect when there is only one bean of this type in the DI container or there is only one
@Primary @ConditionalOnExpression : When the result of the SpEL expression is true
@ConditionalOnProperty : It takes effect when the parameter settings or values are the same
@ConditionalOnResource : It takes effect when the specified file exists Effective
@ConditionalOnJndi: Effective when the specified JNDI exists
@ConditionalOnJava: Effective when the specified Java version exists
@ConditionalOnWebApplication: Effective in a Web application environment
@ConditionalOnNotWebApplication: Effective in a non-Web application environment
classpath @ConditionalOnMissingClass : It takes effect when the class does not exist in the classpath @ConditionalOnBean : It takes effect
when the type of bean exists in the
DI container @ConditionalOnMissingBean : It takes effect when the type of bean does not exist in the DI container
@ConditionalOnSingleCandidate : It takes effect when there is only one bean of this type in the DI container or there is only one
@Primary @ConditionalOnExpression : When the result of the SpEL expression is true
@ConditionalOnProperty : It takes effect when the parameter settings or values are the same
@ConditionalOnResource : It takes effect when the specified file exists Effective
@ConditionalOnJndi: Effective when the specified JNDI exists
@ConditionalOnJava: Effective when the specified Java version exists
@ConditionalOnWebApplication: Effective in a Web application environment
@ConditionalOnNotWebApplication: Effective in a non-Web application environment
@Conditional({OnClassCondition.class}) public @interface ConditionalOnClass { // ... }
public class OnClassCondition extends SpringBootCondition implements ... { // ... // MatchType.PRESENT determines whether the specified class exists in the classpath }
public abstract class SpringBootCondition implements Condition { // ... }
execution order
quote
@AutoConfigureAfter: load after
the specified configuration class is initialized @AutoConfigureBefore: load @AutoConfigureOrder before the specified configuration class is initialized
: the smaller the number, the earlier the initialization
the specified configuration class is initialized @AutoConfigureBefore: load @AutoConfigureOrder before the specified configuration class is initialized
: the smaller the number, the earlier the initialization
(3) Check the actual configuration of the project.
After the DEBUG mode is turned on, you can see the specific automatic configuration results in the console.
/src/main/resources/application.properties
quote
debug=true
quote
=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
DispatcherServletAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class
(OnClassCondition)
- @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched:
- @ConditionalOnClass found required class 'javax.servlet.ServletRegistration'; @ConditionalOnMissingClass did not find unwanted class
(OnClassCondition)
- Default DispatcherServlet did not find dispatcher servlet beans (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition)
.......
Negative matches:
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory'
(OnClassCondition)
AopAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)
.......
Exclusions:
-----------
None
Unconditional classes:
----------------------
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
DispatcherServletAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class
(OnClassCondition)
- @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched:
- @ConditionalOnClass found required class 'javax.servlet.ServletRegistration'; @ConditionalOnMissingClass did not find unwanted class
(OnClassCondition)
- Default DispatcherServlet did not find dispatcher servlet beans (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition)
.......
Negative matches:
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory'
(OnClassCondition)
AopAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)
.......
Exclusions:
-----------
None
Unconditional classes:
----------------------
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
For example, you can see that SpringBoot is enabled by default:
quote
DispatcherServletAutoConfiguration Register DispatcherServlet
EmbeddedServletContainerAutoConfiguration.EmbeddedTomcat Register Tomcat container
ErrorMvcAutoConfiguration Register exception handler
HttpEncodingAutoConfiguration Register encoding filter CharacterEncodingFilter
HttpMessageConvertersAutoConfiguration Register json or xml processor
JacksonAutoConfiguration Register json object parser
MultipartAutoConfiguration Register file transfer processor
TransactionAutoConfiguration Register transaction management processor
ValidationAutoConfiguration Register data validation The processor
WebMvcAutoConfiguration registers SpringMvc related processors
EmbeddedServletContainerAutoConfiguration.EmbeddedTomcat Register Tomcat container
ErrorMvcAutoConfiguration Register exception handler
HttpEncodingAutoConfiguration Register encoding filter CharacterEncodingFilter
HttpMessageConvertersAutoConfiguration Register json or xml processor
JacksonAutoConfiguration Register json object parser
MultipartAutoConfiguration Register file transfer processor
TransactionAutoConfiguration Register transaction management processor
ValidationAutoConfiguration Register data validation The processor
WebMvcAutoConfiguration registers SpringMvc related processors
(4) Turn off the overall invalidation of automatic configuration
a) Use @Configuration @ComponentScan instead of @SpringBootApplication.
b) parameter settings
src/main/resources/application.properties
quote
spring.boot.enableautoconfiguration=false
partially nullified
@SpringBootApplication(exclude=HibernateJpaAutoConfiguration.class)
或
src/main/resources/application.properties
quote
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
或
src/main/resources/application.properties
quote
spring.autoconfigure.exclude[0]=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
spring.autoconfigure.exclude[1]=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
spring.autoconfigure.exclude[2]=org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
spring.autoconfigure.exclude[3]=org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
spring.autoconfigure.exclude[1]=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
spring.autoconfigure.exclude[2]=org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
spring.autoconfigure.exclude[3]=org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
Reference:
http://qiita.com/kazuki43zoo/items/8645d9765edd11c6f1dd
http://d.hatena.ne.jp/Kazuhira/20170219/1487513127