SpringBoot基礎篇Bean之自動載入
前面一篇介紹了Bean的常用姿勢,在一個專案中,可能不會出現什麼問題,可如果你提供了一個Jar包供第三方使用者使用,那麼你這個jar包中的Bean,能被第三方載入麼?
本篇博文將主要介紹AutoConfig相關的內容,即如果我想提供一個jar包供第三方在Spring的環境下使用時,可以怎麼做
I. AutoConfiguration
通常來講,要想實現上面的場景,建議是藉助@Configuration
註解的配置類來管理你自己的bean,這樣對於其他使用方而言,只需要載入到你的配置類,就可以註冊你的所有bean了
1. 包路徑掃描使用姿勢
首先是在你的工程中定義一個配置類,如下
@Configuration
@ComponentScan("com.git.hui.boot.autoconfig")
public class SelfAutoConfig {
}
這個配置類功能比較簡單,指明掃描的包路徑,然後這個配置類如何給使用方使用呢?
將配置放在指定的檔案中即可,使用者會自動載入,從而避免的程式碼的侵入
- 在資源目錄下新建目錄 META-INF
- 在 META-INF 目錄下新建檔案
spring.factories
- 在檔案中新增
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.git.hui.boot.autoconfig.SelfAutoConfig
說明,如果需要換行時,可以如下
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.git.hui.boot.autoconfig.SelfAutoConfig,`
com.git.hui.boot.autoconfig.SelfAutoConfig2,`
然後使用方就可以愉快的使用你的bean了,定義一個測試的Bean如下
@Slf4j
@Component
public class AutoBean {
private String name;
public AutoBean () {
this("defaultAutoBean");
}
public AutoBean(String name) {
this.name = name;
log.info("AutoBean load time: {}", System.currentTimeMillis());
}
public String getName() {
return name;
}
}
2. 定義Bean使用方式
直接在Config配置中,定義Bean,可以說是更加常見的方式,特別是當你的bean不是那麼多的時候,推薦使用這種方式,便於集中管理
@Slf4j
public class AutoConfBean {
private String name;
public AutoConfBean(String name) {
this.name = name;
log.info("AutoConfBean load time: {}", System.currentTimeMillis());
}
public String getName() {
return name;
}
}
對應的配置類
@Configuration
@ComponentScan("com.git.hui.boot.autoconfig")
public class SelfAutoConfig {
@Bean
public AutoConfBean autoConfBean() {
return new AutoConfBean("auto load + " + System.currentTimeMillis());
}
}
3. 例項演示
在新工程中,測試前面的工程的bean,看是否可以正常載入,這一小結結合原始碼執行檢視,更有助於理解
原始碼工程說明
- 005-autoconfig 提供自動載入的Bean的工程,內部定義了前面的兩個測試Bean和配置檔案
- 004-bean 測試引入第三方jar中Bean的工程
測試程式碼如下,已刪除無關的內容
@RestController
public class DemoController {
/**
* 測試引入第三方包的情況
*/
@Autowired
private AutoBean autoBean;
@Autowired
private AutoConfBean autoConfBean;
@GetMapping(path = "/show")
public String show(String name) {
Map<String, String> map = new HashMap<>(4);
// ...
map.put("auto", autoBean != null ? autoBean.getName() : "null");
map.put("autoConf", autoConfBean != null ? autoConfBean.getName() : "null");
return JSON.toJSONString(map);
}
}
演示圖如下:
4. 小結
本篇的內容比較簡單,東西也不多,主要就是在自己的專案中新增一個Configuration
配置類,然後在資源目錄下新增 META-INF/spring.factories
即可
上面這麼做,其實和Java本身的SPI機制有點像,都是講一些類資訊寫在約定的檔案中,然後由框架層來獲取檔案中的內容然後進行解析,後面在原始碼篇,會涉及到整個處理流程;現在知道大致是這麼玩的就行
從簡單的使用來講,上面可以滿足一般場景,但是實際的應用中,還有其他的問題
- 我直接依賴或間接依賴了很多jar包,但是有些包並不想引入他們定義的AutoConfig怎麼辦?(如進行redis操作的Lettuce和Jedis,只需要一個生效即可)
- 如我的Jar包工作的前提是需要引入其他的jar包,但是我不知道使用我的地方是否提供了這個依賴,如何處理?(如只有Spring容器中有BeanA之後,我定義的Bean才生效)
- Bean初始化順序的問題
II. 其他
0. 相關
a. 參考
b. 專案
1. 一灰灰Blog
一灰灰的個人部落格,記錄所有學習和工作中的博文,歡迎大家前去逛逛
2. 宣告
盡信書則不如,以上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激
- QQ: 一灰灰/3302797840
3. 掃描關注
一灰灰blog
知識星球