springboot 自動(dòng)配置 主要通過
@EnableAutoConfiguration
,@Conditional
,@EnableConfigurationProperties
或者@ConfigurationProperties
幾個(gè)注解來進(jìn)行自動(dòng)配置。
@EnableAutoConfiguration
開啟自動(dòng)配置,主要作用就是調(diào)用core包里的loadFactoryNames()
戚揭,將autoconfig
包里的已經(jīng)寫好的自動(dòng)配置加載進(jìn)來。
@Conditional
條件注解携取,通過判斷類路徑下有沒有相應(yīng)配置的jar包來確定是否加載和自動(dòng)配置這個(gè)類,
@EnableConfigurationProperties
的作用就是,給自動(dòng)配置提供具體的配置參數(shù),只需要寫在application.properties
中伟墙,就可以通過映射寫入配置類的Pojo
屬性中。
一.@EnableAutoConfiguration
@Enable*注釋并不是SpringBoot
新發(fā)明的注釋滴铅,Spring 3框架就引入了這些注釋,用這些注釋替代XML配置文件就乓。比如:
@EnableTransactionManagement
注釋汉匙,它能夠聲明事務(wù)管理
@EnableWebMvc
注釋,它能啟用Spring MVC
@EnableScheduling
注釋生蚁,它可以初始化一個(gè)調(diào)度器噩翠。
這些注釋事實(shí)上都是簡單的配置,通過@Import
注釋導(dǎo)入邦投。
從啟動(dòng)類的@SpringBootApplication進(jìn)入伤锚,在里面找到了@EnableAutoConfiguration,
@EnableAutoConfiguration里通過@Import導(dǎo)入了EnableAutoConfigurationImportSelector
,
進(jìn)入他的父類AutoConfigurationImportSelector
找到selectImports()
方法,他調(diào)用了getCandidateConfigurations()
方法志衣,在這里屯援,這個(gè)方法又調(diào)用了Spring Core包中的loadFactoryNames()
方法。這個(gè)方法的作用是念脯,會(huì)查詢META-INF/spring.factories
文件中包含的JAR
文件狞洋。
當(dāng)找到spring.factories文件后,SpringFactoriesLoader將查詢配置文件命名的屬性绿店。
Jar
文件在org.springframework.boot.autoconfigure的spring.factories
spring.factories
內(nèi)容如下(截取部分),在這個(gè)文件中吉懊,可以看到一系列Spring Boot自動(dòng)配置的列表
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.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
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.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
下面我們來看自動(dòng)配置redis的細(xì)節(jié),RedisAutoConfiguration:
RedisAutoConfiguration
這個(gè)類進(jìn)行了簡單的Spring配置假勿,聲明了Redis所需典型Bean借嗽,和其它很多類一樣,重度依賴于Spring Boot注釋:
1)@ConditionOnClass激活一個(gè)配置转培,當(dāng)類路徑中存在這個(gè)類時(shí)才會(huì)配置該類
2)@EnableConfigurationProperties自動(dòng)映射一個(gè)POJO到Spring Boot配置文件(默認(rèn)是application.properties文件)的屬性集恶导。
3)@ConditionalOnMissingBean啟用一個(gè)Bean定義,但必須是這個(gè)Bean之前未定義過才有效堡距。
還可以使用@ AutoConfigureBefore注釋甲锡、@AutoConfigureAfter注釋來定義這些配置類的載入順序兆蕉。
著重了解@Conditional注釋,Spring 4框架的新特性
此注釋使得只有在特定條件滿足時(shí)才啟用一些配置缤沦。SrpingBoot的AutoConfig大量使用了@Conditional虎韵,它會(huì)根據(jù)運(yùn)行環(huán)境來動(dòng)態(tài)注入Bean。這里介紹一些@Conditional的使用和原理缸废,并自定義@Conditional來自定義功能包蓝。
- @Conditional是SpringFramework的功能,SpringBoot在它的基礎(chǔ)上定義了
- @ConditionalOnClass企量,@ConditionalOnProperty等一系列的注解來實(shí)現(xiàn)更豐富的內(nèi)容测萎。
具體幾個(gè)@Conditon*注解的含義
@ConditionalOnBean
僅僅在當(dāng)前上下文中存在某個(gè)對象時(shí),才會(huì)實(shí)例化一個(gè)Bean
@ConditionalOnClass
某個(gè)class位于類路徑上届巩,才會(huì)實(shí)例化一個(gè)Bean)硅瞧,該注解的參數(shù)對應(yīng)的類必須存在,否則不解析該注解修飾的配置類
@ConditionalOnExpression
當(dāng)表達(dá)式為true的時(shí)候恕汇,才會(huì)實(shí)例化一個(gè)Bean
@ConditionalOnMissingBean
僅僅在當(dāng)前上下文中不存在某個(gè)對象時(shí)腕唧,才會(huì)實(shí)例化一個(gè)Bean,該注解表示瘾英,如果存在它修飾的類的bean枣接,則不需要再創(chuàng)建這個(gè)bean,可以給該注解傳入?yún)?shù)例如@ConditionOnMissingBean(name = "example")缺谴,這個(gè)表示如果name為“example”的bean存在但惶,這該注解修飾的代碼塊不執(zhí)行
@ConditionalOnMissingClass
某個(gè)class類路徑上不存在的時(shí)候,才會(huì)實(shí)例化一個(gè)Bean
@ConditionalOnNotWebApplication
不是web應(yīng)用時(shí)湿蛔,才會(huì)執(zhí)行
2.Properties系列注釋
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "may")
在需要注入配置的類上加上這個(gè)注解膀曾,prefix的意思是,以該前綴打頭的配置阳啥,以下是例子
@ConfigurationProperties(prefix = "may")
public class User {
private String name;
private String gender;
//省略setter,getter方法
}
application.yml中的配置
may
name: youjie
gender: man
如果不用系統(tǒng)初始的application.yml配置類妓肢,而是使用自己的如youjie.yml,可以如下配置
@ConfigurationProperties(prefix = "may",locations = "classpath:youjie.yml")
public class User2 {
private String name;
private String gender;
//省略setter,getter方法
}
過時(shí):由于Spring-boot 1.5.2版本移除了苫纤,locations這個(gè)屬性,因此上述這種方式在最新的版本中過時(shí)碉钠。
@PropertySource
Spring-boot 1.5.2版本之后,采用下面這種方式
@Component
//@PropertySource只能加載.properties文件卷拘,需要將上面的yml文件喊废,改為.properties文件
@PropertySource("classpath:may.properties")
@ConfigurationProperties(prefix="may")
public class User2 {
private String name;
private String gender;
//省略setter,getter方法
}
@EnableConfigurationProperties
最后注意在spring Boot入口類加上@EnableConfigurationProperties
@SpringBootApplication
@EnableConfigurationProperties({User.class,User2.class})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
其實(shí)這里@EnableConfigurationProperties({User.class,User2.class}) 可以省略