@EnableAutoConfiguration
在spring boot项目中如果在@Configuration
类(说明这个类是配置类,能被自动扫描到)同时添加注解@EnableAutoConfiguration
就会获得很多很方便的开箱即用的配置,同时@EnableAutoConfiguration
放在哪里就隐含了搜索自动化配置类的路径@EnableAutoConfiguration
注解中@Import
了EnableAutoConfigurationImportSelector
虽然自动配置是非侵入的,且会被你自身的配置覆盖(主要采用了条件注入的方式,见@EnableAutoConfiguration),你也可以在一开始就使用@EnableAutoConfiguration
注解的exclude
属性,将不是你所想要的自动化配置类(auto-configure classes)禁用掉
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;
@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
如果该类不在classpath中,你可以使用该注解的
excludeName
属性,并指定全限定名来达到相同效果。最后,你可以通过spring.autoconfigure.exclude属性(在属性文件application.properties中,多个值用逗号隔开)exclude多个自动配置项(一个自动配置项集合)。excludeName
和exclude
都是传入一个数组通过注解级别或属性文件中的
exclude
属性都可以定义排除项。
EnableAutoConfigurationImportSelector
使用SpringFactoriesLoader#loadFactoryNames
搜索jar包中的META-INF/spring.factories
.如果找到这个文件,SpringFactoriesLoader
就会搜索该文件中的一个配置org.springframework.boot.autoconfigure.EnableAutoConfiguration
,并读取后面的值。META-INF/spring.factories
会在spring-boot-autoconfigure.jar
下
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
# 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.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
##...省略
# Template availability providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.velocity.VelocityTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider
org.springframework.boot.autoconfigure.EnableAutoConfiguration
后面配置了几十个*AutoConfiguration
类,这些类就是默认各个模块的默认配置。*AutoConfiguration
才是提工默认配置的地方
(这些配置原本是需要我们自己写在项目里的,比如使用了Thymeleaf,就需要有个配置类或者老做法新建一个配置xml配置Thymeleaf)
@Configuration
@EnableConfigurationProperties(ThymeleafProperties.class)
@ConditionalOnClass(SpringTemplateEngine.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class ThymeleafAutoConfiguration {
private static final Log logger = LogFactory.getLog(ThymeleafAutoConfiguration.class);
@Configuration
@ConditionalOnMissingBean(name = "defaultTemplateResolver")
public static class DefaultTemplateResolverConfiguration {
@Autowired
private ThymeleafProperties properties;
@Autowired
private ApplicationContext applicationContext;
@PostConstruct
public void checkTemplateLocationExists() {
boolean checkTemplateLocation = this.properties.isCheckTemplateLocation();
if (checkTemplateLocation) {
TemplateLocation location = new TemplateLocation(
this.properties.getPrefix());
if (!location.exists(this.applicationContext)) {
logger.warn("Cannot find template location: " + location
+ " (please add some templates or check "
+ "your Thymeleaf configuration)");
}
}
}
//other code
}
@Configuration
定义该为一个配置类@EnableConfigurationProperties(ThymeleafProperties.class)
表示能在ThymeleafProperties
类中使用@ConfigurationProperties
注解自动从配置文件中绑定属性(不需要@value
方式)
查看一下ThymeleafProperties
类,@ConfigurationProperties("spring.thymeleaf")
表明,默认从applciation.properties
中读取前缀为spring.thymeleaf
的属性,例如spring.thymeleaf.prefix=指定html路径
@ConfigurationProperties("spring.thymeleaf")
public class ThymeleafProperties {
}
而以下几个注解,是非侵入式配置的关键,即只有满足某些条件的情况下该配置才会生效(Spring高级装配之条件装配)
@ConditionalOnClass(SpringTemplateEngine.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
@ConditionalOnMissingBean
@ConditionalOnClass
conditional注解威力很强大,常见的有:
@ConditionalOnBean
@ConditionalOnClass
@ConditionalOnExpression
@ConditionalOnMissingBean
@ConditionalOnMissingClass
@ConditionalOnNotWebApplication
@ConditionalOnResource
@ConditionalOnWebApplication