1. 程式人生 > >SpringBoot基礎篇Bean之自動載入

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);
    }
}

演示圖如下:

gif.gif

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

QrCode

知識星球

goals