Spring Boot 入门 - 进阶篇(7)- 自动配置(AutoConfigure)

自动配置是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) 应用入口 
Java代码   收藏代码
  1. @SpringBootApplication  
  2. public class SpringBootDemoApplication {  
  3.   
  4.     public static void main(String[] args) {  
  5.         SpringApplication.run(SpringBootDemoApplication.class, args);  
  6.     }  
  7.   
  8. }  


b) 类注解 @SpringBootApplication = @EnableAutoConfiguration + @ComponentScan + @Configuration 
Java代码   收藏代码
  1. @SpringBootConfiguration  
  2. @EnableAutoConfiguration  
  3. @ComponentScan(excludeFilters = {  
  4.         @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),  
  5.         @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })  
  6. public @interface SpringBootApplication {  
  7.     // ...  
  8. }  
  9.   
  10. @Configuration  
  11. public @interface SpringBootConfiguration {  
  12.     // ...  
  13. }  


c)开启自动配置注解 @EnableAutoConfiguration 
Java代码   收藏代码
  1. @AutoConfigurationPackage  
  2. @Import(EnableAutoConfigurationImportSelector.class)  
  3. public @interface EnableAutoConfiguration {  
  4.     // ...  
  5. }  


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。 
Java代码   收藏代码
  1. public class ServletInitializer extends SpringBootServletInitializer {  
  2.     @Override  
  3.     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {  
  4.         return application.sources(SpringBootDemoApplication.class);  
  5.     }  
  6. }  


配置类也可自行导入 
Java代码   收藏代码
  1. @Configuration  
  2. @Import({  
  3.         DispatcherServletAutoConfiguration.class,  
  4.         EmbeddedServletContainerAutoConfiguration.class,  
  5.         ErrorMvcAutoConfiguration.class,  
  6.         HttpEncodingAutoConfiguration.class,  
  7.         HttpMessageConvertersAutoConfiguration.class,  
  8.         JacksonAutoConfiguration.class,  
  9.         MultipartAutoConfiguration.class,  
  10.         ServerPropertiesAutoConfiguration.class,  
  11.         WebMvcAutoConfiguration.class  
  12. })  
  13. @ComponentScan  
  14. public class SpringBootDemoApplication {  
  15.     public static void main(String[] args) {  
  16.         SpringApplication.run(SpringBootDemoApplication.class, args);  
  17.     }  
  18. }  


(2)自动配置类内部构成  

举例查看 org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration 

Java代码   收藏代码
  1. @Configuration  
  2. @ConditionalOnWebApplication(type = Type.SERVLET)  
  3. @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class })  
  4. @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)  
  5. @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)  
  6. @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class })  
  7. public class WebMvcAutoConfiguration {  
  8.   
  9.     @Bean  
  10.     @ConditionalOnMissingBean(HiddenHttpMethodFilter.class)  
  11.     public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {  
  12.         return new OrderedHiddenHttpMethodFilter();  
  13.     }  
  14.   
  15.     // ...  
  16.   
  17. }  


条件配置  基于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应用环境下起效

Java代码   收藏代码
  1. @Conditional({OnClassCondition.class})  
  2. public @interface ConditionalOnClass {  
  3.     // ...  
  4. }  

Java代码   收藏代码
  1. public class OnClassCondition extends SpringBootCondition implements ... {  
  2.     // ...  
  3.     // MatchType.PRESENT 判断classpath里是否存在指定类  
  4. }  

Java代码   收藏代码
  1. public abstract class SpringBootCondition implements Condition {  
  2.     // ...  
  3. }  


执行顺序  
引用
@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


部分无效化 

Java代码   收藏代码
  1. @SpringBootApplication(exclude=HibernateJpaAutoConfiguration.class)  

或 
src/main/resources/application.properties 
引用
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration


Java代码   收藏代码
  1. @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
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值