Spring-boot的一個重要特性就是提供了各類各樣的AutoConfiguration。例如DataSourceAutoConfiguration。這樣咱們只須要在配置文件中進行以下配置mysql
spring: datasource: url: jdbc:mysql://xxxxxxxxxxx/realname username: xxxxx password: xxxxx driverClassName: com.mysql.jdbc.Driver
Spring-Boot就會在容器中按照咱們的配置的信息注入一個DataSource。那麼Spring boot是怎麼知道 DataSourceAutoConfiguration是自動配置類?其實很簡單:spring
Spring Boot 這種用「約定優於配置」思想能夠大大的簡化配置代碼的編寫。那麼,咱們就能夠按照上面的套路來編寫一個Spring-Boot的自動配置類吧sql
如今有一個配置Bean——PrintAfterInitBean,須要Spring容器啓動之後,打印一次消息,而且該消息的內容是在配置文件中定義app
代碼以下,由於只是一個簡單例子,這裏的配置Bean其實能夠是其餘任何複雜配置Bean,例如DataSource。每每一個公共包須要多個這樣配置Bean才能完成其配置。ide
public class PrintAfterInitBean implements InitializingBean { private String message; public void afterPropertiesSet() throws Exception { System.out.println(message); } //setter getter }
若是搜索Spring Boot下面的類,你會發現其實有不少名字形如xxxAutoConfiguration的類,這些類都是Spirng Boot爲咱們作的一些快捷配置類。 建立一個TestAutoConfig,做爲一個自動配置類微服務
@Configuration public class TestAutoConfig { @Bean @ConfigurationProperties(prefix = "init") @ConditionalOnMissingBean(PrintAfterInitBean.class) @ConditionalOnProperty(prefix = "init",value = "message") public PrintAfterInitBean printAfterInitBean() { return new PrintAfterInitBean(); } }
在resources下面建立META-INF/spring.factories, 而後在文件中把第二步的類配置進去編碼
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.netease.xxx.xxx.UrsPropertyAutoConfig
這樣就完成一個Spring Boot自動配置,若是存在init.message的配置,那麼spring boot啓動的時候就會打印init.message配置對應值。url
Spring Boot的自動配置爲咱們在編寫一個重複的配置代碼(或者xml文件)中提供一套簡便的部署方式,這樣當用其餘spring boot的項目依賴咱們jar時候,配置起來就十分方便拉。從代碼能夠看出,Spring Boot 其實並無什麼實質性的創新,只是把一些「約定」的配置信息轉換原來經過代碼或xml實現的配置。spa
前面已經介紹過,@ConditionalOnXXX 系列主要是自動配置是否生效,例如ConditionalOnClass,就是在某個Class存在的狀況下才生效。這一系列的註解經過名字就知道用法,所以再也不作過多的介紹。@ConditionalOnXXX 能夠用於類名和方法名上。.net
用DataSourceAutoConfiguration 代碼來講明,
@Configuration // 注:當存在DataSource.class 和 EmbeddedDatabaseType.class 存在的狀況下,該配置路徑才生效 @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) @EnableConfigurationProperties(DataSourceProperties.class) @Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class }) public class DataSourceAutoConfiguration { private static final Log logger = LogFactory .getLog(DataSourceAutoConfiguration.class); @Bean // 注:只有當BeanFactory中不存在DataSourceInitializer類的Bean的狀況下才會有效 @ConditionalOnMissingBean public DataSourceInitializer dataSourceInitializer(DataSourceProperties properties, ApplicationContext applicationContext) { return new DataSourceInitializer(properties, applicationContext); } ... }
自動配置的核心思想就是不侵佔用戶的代碼,相似於「你有就用你的,你沒有我就幫你作默認設置」。所以,咱們在本身開發一個自動配置類的時候也須要注意這一點,否則就有點霸王條款的感受
通常咱們的自動配置類都會依賴外部的配置信息,而這些外部的配置信息能夠封裝成一個類,相似上面DataSourceAutoConfiguration中的@EnableConfigurationProperties(DataSourceProperties.class),DataSourceProperties類就是用來保存DataSource相關的配置信息。「約定優於配置」的思想就在這裏體現,若是配置信息是以spring.datasource爲前綴,那麼配置信息都會注入到DataSourceProperties類中,供DataSourceAutoConfiguration使用。
@ConfigurationProperties(prefix = "spring.datasource") public class DataSourceProperties implements BeanClassLoaderAware, EnvironmentAware, InitializingBean { ... private Class<? extends DataSource> type; private String driverClassName; private String url; private String username; private String password; ...
在一些特殊的狀況下,一些自動配置類須要在某一些其餘配置類後進行,例如依賴另一個自動配置的Bean,這個時候就@AutoConfigureAfter來進行約束。
@Import也是比較常見的一個配置註解,主要用於引入其餘配置類,可是另一個比較有用的配置就是引入一個ImportBeanDefinitionRegistrar接口,而這個就是用於使用在ApplicationContext初始化階段的時候,註冊(register)一些BeanDefinition。固然常見的Bean是能夠經過@Bean註解注入,可是一些Spring ApplicationContext啓動過程當中用的到一些Bean則不行,例如BeanPostProcessor,BeanFactoryPostProcessor。
Spring Boot 核心思想就是「約定優於配置」思想,在建立一個微服務的時候有不少得天獨厚的優點,每每只用短短几行配置,就能夠部署一個應用。這樣在編碼更多的是一些業務層面。而若是咱們本身編寫的一個公共包也可以經過短短几行配置便可以完成,不只僅是代碼層面的減小,更是接入方來講是一種「一站式服務」體驗。固然前提是接入方也是使用的Spring Boot。