自动配置是Spring Boot的最大亮点,完美的展示了CoC约定由于配置。Spring Boot能自动配置Spring各种子项目(Spring MVC, Spring Security, Spring Data, Spring Cloud, Spring Integration, Spring Batch等)以及第三方开源框架所需要定义的各种Bean。
Spring Boot内部定义了各种各样的XxxxAutoConfiguration配置类,预先定义好了各种所需的Bean。只有在特定的情况下这些配置类才会被起效。
(1)如何导入的自动配置类
查看源码可以看看自动配置类是如何被引入的。
a) 应用入口
- @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)开启自动配置注解 @EnableAutoConfiguration
- @AutoConfigurationPackage
- @Import(EnableAutoConfigurationImportSelector.class)
- public @interface EnableAutoConfiguration {
-
- }
d)导入配置类 EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector
在AutoConfigurationImportSelector类中可以看到通过 SpringFactoriesLoader.loadFactoryNames()
把 spring-boot-autoconfigure-1.5.1.RELEASE.jar/META-INF/spring.factories 下
引用
# 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
应用启动后是如何加载这些类的呢?
通过执行SpringApplication.run()方法,会把当前的SpringBootDemoApplication作为source传入而在SpringApplication类中还会读取spring.factories中的设置一并构建应用的Context。
spring-boot-1.5.1.RELEASE.jar/META-INF/spring.factories
引用
# 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
spring-boot-autoconfigure-1.5.1.RELEASE.jar/META-INF/spring.factories
引用
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
相应在做war时也是把当前的SpringBootDemoApplication作为source传给了ServletInitializer。
- public class ServletInitializer extends SpringBootServletInitializer {
- @Override
- protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
- return application.sources(SpringBootDemoApplication.class);
- }
- }
配置类也可自行导入
- @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)自动配置类内部构成
举例查看 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();
- }
-
-
-
- }
条件配置
基于Spring的@Conditional,SpringBoot提供了丰富的条件配置:
引用
@ConditionalOnClass : classpath中存在该类时起效
@ConditionalOnMissingClass : classpath中不存在该类时起效
@ConditionalOnBean : DI容器中存在该类型Bean时起效
@ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效
@ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或@Primary的只有一个时起效
@ConditionalOnExpression : SpEL表达式结果为true时
@ConditionalOnProperty : 参数设置或者值一致时起效
@ConditionalOnResource : 指定的文件存在时起效
@ConditionalOnJndi : 指定的JNDI存在时起效
@ConditionalOnJava : 指定的Java版本存在时起效
@ConditionalOnWebApplication : Web应用环境下起效
@ConditionalOnNotWebApplication : 非Web应用环境下起效
- @Conditional({OnClassCondition.class})
- public @interface ConditionalOnClass {
-
- }
- public class OnClassCondition extends SpringBootCondition implements ... {
-
-
- }
- public abstract class SpringBootCondition implements Condition {
-
- }
执行顺序
引用
@AutoConfigureAfter:在指定的配置类初始化后再加载
@AutoConfigureBefore:在指定的配置类初始化前加载
@AutoConfigureOrder:数越小越先初始化
(3)查看项目实际配置了什么
运行时开启DEBUG模式后即可在控制台看到具体的自动配置结果。
/src/main/resources/application.properties
引用
debug=true
引用
=========================
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
比如可以看到SpringBoot默认开启了:
引用
DispatcherServletAutoConfiguration 注册DispatcherServlet
EmbeddedServletContainerAutoConfiguration.EmbeddedTomcat 注册Tomcat容器
ErrorMvcAutoConfiguration 注册异常处理器
HttpEncodingAutoConfiguration 注册编码过滤器CharacterEncodingFilter
HttpMessageConvertersAutoConfiguration 注册json或者xml处理器
JacksonAutoConfiguration 注册json对象解析器
MultipartAutoConfiguration 注册文件传输处理器
TransactionAutoConfiguration 注册事物管理处理器
ValidationAutoConfiguration 注册数据校验处理器
WebMvcAutoConfiguration 注册SpringMvc相关处理器
(4)关闭自动配置
全体无效化
a)使用@Configuration @ComponentScan 代替 @SpringBootApplication。
b)参数设置
src/main/resources/application.properties
引用
spring.boot.enableautoconfiguration=false
部分无效化
- @SpringBootApplication(exclude=HibernateJpaAutoConfiguration.class)
或
src/main/resources/application.properties
引用
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
- @SpringBootApplication(exclude={DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
或
src/main/resources/application.properties
引用
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
参考:
http://qiita.com/kazuki43zoo/items/8645d9765edd11c6f1dd
http://d.hatena.ne.jp/Kazuhira/20170219/1487513127