本文首發於我的網站,原文地址:http://www.javaadu.online/?p=535,如需轉載,請註明出處java
在學習Spring Boot的過程當中,接觸最多的就是starter。能夠認爲starter是一種服務——使得使用某個功能的開發者不須要關注各類依賴庫的處理,不須要具體的配置信息,由Spring Boot自動經過classpath路徑下的類發現須要的Bean,並織入bean。舉個例子,spring-boot-starter-jdbc這個starter的存在,使得咱們只須要在BookPubApplication下用@Autowired
引入DataSource的bean就能夠,Spring Boot會自動建立DataSource的實例。面試
這裏咱們會用一個不太規範的starter展現Spring Boot的自動配置的運行原理。Spring Boot的自動配置、Command-line Runner一文中曾利用StartupRunner類在程序運行啓動後首先查詢數據庫中書的數目,如今換個需求:在系統啓動後打印各個實體的數量。spring
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot</artifactId> <!-- version繼承父模塊的--> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> <version>1.9.3.RELEASE</version> </dependency></dependencies>
package com.test.bookpubstarter.dbcount; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.data.repository.CrudRepository; import java.util.Collection; public class DbCountRunner implements CommandLineRunner { protected final Logger logger = LoggerFactory.getLogger(DbCountRunner.class); private Collection<CrudRepository> repositories; public DbCountRunner(Collection<CrudRepository> repositories) { this.repositories = repositories; } @Override public void run(String... strings) throws Exception { repositories.forEach(crudRepository -> { logger.info(String.format("%s has %s entries", getRepositoryName(crudRepository.getClass()), crudRepository.count())); }); } private static String getRepositoryName(Class crudRepositoryClass) { for (Class repositoryInterface : crudRepositoryClass.getInterfaces()) { if (repositoryInterface.getName().startsWith("com.test.bookpub.repository")) { return repositoryInterface.getSimpleName(); } } return "UnknownRepository"; } }
package com.test.bookpubstarter.dbcount; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.repository.CrudRepository; import java.util.Collection; @Configuration public class DbCountAutoConfiguration { @Bean public DbCountRunner dbCountRunner(Collection<CrudRepository> repositories) { return new DbCountRunner(repositories); } }
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.test.bookpubstarter.dbcount.DbCountAutoConfiguration
<dependency> <groupId>com.test</groupId> <artifactId>db-count-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
正規的starter是一個獨立的工程,而後在maven中新倉庫註冊發佈,其餘開發人員就可使用你的starter了。數據庫
常見的starter會包括下面幾個方面的內容:後端
在應用程序啓動過程當中,Spring Boot使用SpringFactoriesLoader類加載器查找org.springframework.boot.autoconfigure.EnableAutoConfiguration關鍵字對應的Java配置文件。Spring Boot會遍歷在各個jar包種META-INF目錄下的spring.factories文件,構建成一個配置文件鏈表。除了EnableAutoConfiguration關鍵字對應的配置文件,還有其餘類型的配置文件:maven
Spring Boot的starter在編譯時不須要依賴Spring Boot的庫。這個例子中依賴spring boot並非由於自動配置要用spring boot,而僅僅是由於須要實現CommandLineRunner接口。ide
@ConditionalOnMissingBean的做用是:只有對應的ban在系統中都沒有被建立,它修飾的初始化代碼塊纔會執行,用戶本身手動建立的bean優先;函數
Spring Boot starter如何找到自動配置文件(xxxxAutoConfiguration之類的文件)?spring-boot
本號專一於後端技術、JVM問題排查和優化、Java面試題、我的成長和自我管理等主題,爲讀者提供一線開發者的工做和成長經驗,期待你能在這裏有所收穫。 學習