1. 程式人生 > >Spring Boot2 系列教程(六)自定義 Spring Boot 中的 starter

Spring Boot2 系列教程(六)自定義 Spring Boot 中的 starter

我們使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 為我們帶來了眾多的自動化配置,有了這些自動化配置,我們可以不費吹灰之力就能搭建一個生產級開發環境,有的小夥伴會覺得這個 Starter 好神奇呀!其實 Starter 也都是 Spring + SpringMVC 中的基礎知識點實現的,今天鬆哥就來帶大家自己來擼一個 Starter ,慢慢揭開 Starter 的神祕面紗!

核心知識

其實 Starter 的核心就是條件註解 @Conditional ,當 classpath 下存在某一個 Class 時,某個配置才會生效,前面鬆哥已經帶大家學習過不少 Spring Boot 中的知識點,有的也涉及到原始碼解讀,大夥可能也發現了原始碼解讀時總是會出現條件註解,其實這就是 Starter 配置的核心之一,大夥有興趣可以翻翻歷史記錄,看看鬆哥之前寫的關於 Spring Boot 的文章,這裡我就不再重複介紹了。

定義自己的 Starter

定義

所謂的 Starter ,其實就是一個普通的 Maven 專案,因此我們自定義 Starter ,需要首先建立一個普通的 Maven 專案,建立完成後,新增 Starter 的自動化配置類即可,如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>2.1.8.RELEASE</version>
</dependency>

配置完成後,我們首先建立一個 HelloProperties 類,用來接受 application.properties 中注入的值,如下:

@ConfigurationProperties(prefix = "javaboy")
public class HelloProperties {
    private static final String DEFAULT_NAME = "江南一點雨";
    private static final String DEFAULT_MSG = "牧碼小子";
    private String name = DEFAULT_NAME;
    private String msg = DEFAULT_MSG;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

這個配置類很好理解,將 application.properties 中配置的屬性值直接注入到這個例項中, @ConfigurationProperties 型別安全的屬性注入,即將 application.properties 檔案中字首為 javaboy 的屬性注入到這個類對應的屬性上, 最後使用時候,application.properties 中的配置檔案,大概如下:

javaboy.name=zhangsan
javaboy.msg=java

關注型別安全的屬性注入,讀者可以參考鬆哥之前的這篇文章:Spring Boot中的yaml配置簡介,這篇文章雖然是講 yaml 配置,但是關於型別安全的屬性注入和 properties 是一樣的。

配置完成 HelloProperties 後,接下來我們來定義一個 HelloService ,然後定義一個簡單的 say 方法, HelloService 的定義如下:

public class HelloService {
    private String msg;
    private String name;
    public String sayHello() {
        return name + " say " + msg + " !";
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

這個很簡單,沒啥好說的。

接下來就是我們的重軸戲,自動配置類的定義,用了很多別人定義的自定義類之後,我們也來自己定義一個自定義類。先來看程式碼吧,一會鬆哥再慢慢解釋:

@Configuration
@EnableConfigurationProperties(HelloProperties.class)
@ConditionalOnClass(HelloService.class)
public class HelloServiceAutoConfiguration {
    @Autowired
    HelloProperties helloProperties;

    @Bean
    HelloService helloService() {
        HelloService helloService = new HelloService();
        helloService.setName(helloProperties.getName());
        helloService.setMsg(helloProperties.getMsg());
        return helloService;
    }
}

關於這一段自動配置,解釋如下:

  • 首先 @Configuration 註解表明這是一個配置類。
  • @EnableConfigurationProperties 註解是使我們之前配置的 @ConfigurationProperties 生效,讓配置的屬性成功的進入 Bean 中。
  • @ConditionalOnClass 表示當專案當前 classpath 下存在 HelloService 時,後面的配置才生效。
  • 自動配置類中首先注入 HelloProperties ,這個例項中含有我們在 application.properties 中配置的相關資料。
  • 提供一個 HelloService 的例項,將 HelloProperties 中的值注入進去。

做完這一步之後,我們的自動化配置類就算是完成了,接下來還需要一個 spring.factories 檔案,那麼這個檔案是幹嘛的呢?大家知道我們的 Spring Boot 專案的啟動類都有一個 @SpringBootApplication 註解,這個註解的定義如下:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM,
                classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}

大家看到這是一個組合註解,其中的一個組合項就是 @EnableAutoConfiguration ,這個註解是幹嘛的呢?

@EnableAutoConfiguration 表示啟用 Spring 應用程式上下文的自動配置,該註解會自動匯入一個名為 AutoConfigurationImportSelector 的類,而這個類會去讀取一個名為 spring.factories 的檔案, spring.factories 中則定義需要載入的自動化配置類,我們開啟任意一個框架的 Starter ,都能看到它有一個 spring.factories 檔案,例如 MyBatis 的 Starter 如下:

那麼我們自定義 Starter 當然也需要這樣一個檔案,我們首先在 Maven 專案的 resources 目錄下建立一個名為 META-INF 的資料夾,然後在資料夾中建立一個名為 spring.factories 的檔案,檔案內容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.javaboy.mystarter.HelloServiceAutoConfiguration

在這裡指定我們的自動化配置類的路徑即可。

如此之後我們的自動化配置類就算完成了。

本地安裝

如果在公司裡,大夥可能需要將剛剛寫好的自動化配置類打包,然後上傳到 Maven 私服上,供其他同事下載使用,我這裡就簡單一些,我就不上傳私服了,我將這個自動化配置類安裝到本地倉庫,然後在其他專案中使用即可。安裝方式很簡單,在 IntelliJ IDEA 中,點選右邊的 Maven Project ,然後選擇 Lifecycle 中的 install ,雙擊即可,如下:

雙擊完成後,這個 Starter 就安裝到我們本地倉庫了,當然小夥伴也可以使用 Maven 命令去安裝。

使用 Starter

接下來,我們來新建一個普通的 Spring Boot 工程,這個 Spring Boot 建立成功之後,加入我們自定義 Starter 的依賴,如下:

<dependency>
    <groupId>org.javaboy</groupId>
    <artifactId>mystarter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

此時我們引入了上面自定義的 Starter ,也即我們專案中現在有一個預設的 HelloService 例項可以使用,而且關於這個例項的資料,我們還可以在 application.properties 中進行配置,如下:

javaboy.name=牧碼小子
javaboy.msg=java

配置完成後,方便起見,我這裡直接在單元測試方法中注入 HelloSerivce 例項來使用,程式碼如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UsemystarterApplicationTests {

    @Autowired
    HelloService helloService;
    @Test
    public void contextLoads() {
        System.out.println(helloService.sayHello());
    }
}

執行單元測試方法,列印日誌如下:

好了,一個簡單的自動化配置類我們就算完成了,是不是很簡單!

總結

本文主要帶領小夥伴自己徒手擼一個 Starter ,使用這種方式幫助大家揭開 Starter 的神祕面紗!大夥有問題可以留言討論。

本文的案例,鬆哥已經上傳到 GitHub上了,地址:https://github.com/lenve/javaboy-code-samples 。

關注公眾號【江南一點雨】,專注於 Spring Boot+微服務以及前後端分離等全棧技術,定期視訊教程分享,關注後回覆 Java ,領取鬆哥為你精心準備的 Java 乾貨!

相關推薦

Spring Boot2 系列教程()定義 Spring Boot starter

我們使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 為我們帶來了眾多的自動化配置,有了這些自動化配置,我們可以不費吹灰之力就能搭建一個生產級開發環境,有的小夥伴會覺得這個 Starter 好神奇呀!其實 Starter 也都是 Spring + SpringMVC

Spring Boot2 系列教程(十五)定義系統啟動任務的兩種方式

在 Servlet/Jsp 專案中,如果涉及到系統任務,例如在專案啟動階段要做一些資料初始化操作,這些操作有一個共同的特點,只在專案啟動時進行,以後都不再執行,這裡,容易想到web基礎中的三大元件( Servlet、Filter、Listener )之一 Listener ,這種情況下,一般定義一個 Serv

Spring Boot2 系列教程(二十三)理解 Spring Data Jpa

有很多讀者留言希望鬆哥能好好聊聊 Spring Data Jpa! 其實這個話題鬆哥以前零零散散的介紹過,在我的書裡也有介紹過,但是在公眾號中還沒和大夥聊過,因此本文就和大家來仔細聊聊 Spring Data 和 Jpa! 本文大綱: 1. 故事的主角 1.1 Jpa 1.1.1 JPA 是什麼 Jav

Spring Boot2 系列教程(二十四)Spring Boot 整合 Jpa

Spring Boot 中的資料持久化方案前面給大夥介紹了兩種了,一個是 JdbcTemplate,還有一個 MyBatis,JdbcTemplate 配置簡單,使用也簡單,但是功能也非常有限,MyBatis 則比較靈活,功能也很強大,據我所知,公司採用 MyBatis 做資料持久化的相當多,但是 MyBat

Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多資料來源

本文是 Spring Boot 整合資料持久化方案的最後一篇,主要和大夥來聊聊 Spring Boot 整合 Jpa 多資料來源問題。在 Spring Boot 整合JbdcTemplate 多資料來源、Spring Boot 整合 MyBatis 多資料來源以及 Spring Boot 整合 Jpa 多資料

Spring Boot2 系列教程(二十八)Spring Boot 整合 Session 共享

這篇文章是鬆哥的原創,但是在第一次釋出的時候,忘了標記原創,結果被好多號轉發,導致我後來整理的時候自己沒法標記原創了。寫了幾百篇原創技術乾貨了,有一兩篇忘記標記原創進而造成的一點點小小損失也能接受,不過還是要和小夥伴們說明一下。 在傳統的單服務架構中,一般來說,只有一個伺服器,那麼不存在 Session

Spring Boot2 系列教程(二十九)Spring Boot 整合 Redis

經過 Spring Boot 的整合封裝與自動化配置,在 Spring Boot 中整合Redis 已經變得非常容易了,開發者只需要引入 Spring Data Redis 依賴,然後簡單配下 redis 的基本資訊,系統就會提供一個 RedisTemplate 供開發者使用,但是今天鬆哥想和大夥聊的不是這種

Spring Boot2 系列教程(三十一)Spring Boot 構建 RESTful 風格應用

RESTful ,到現在相信已經沒人不知道這個東西了吧!關於 RESTful 的概念,我這裡就不做過多介紹了,傳統的 Struts 對 RESTful 支援不夠友好 ,但是 SpringMVC 對於 RESTful 提供了很好的支援,常見的相關注解有: @RestController @GetMapping

Spring Boot2 系列教程(十八)Spring Boot 定義 SpringMVC 配置

用過 Spring Boot 的小夥伴都知道,我們只需要在專案中引入 spring-boot-starter-web 依賴,SpringMVC 的一整套東西就會自動給我們配置好,但是,真實的專案環境比較複雜,系統自帶的配置不一定滿足我們的需求,往往我們還需要結合實際情況自定義配置。 自定義配置就有講究了,由於

Spring Boot2 系列教程(十)定時任務的兩種實現方式

在 Spring + SpringMVC 環境中,一般來說,要實現定時任務,我們有兩中方案,一種是使用 Spring 自帶的定時任務處理器 @Scheduled 註解,另一種就是使用第三方框架 Quartz ,Spring Boot 源自 Spring+SpringMVC ,因此天然具備這兩個 Spring

Spring Boot2 系列教程(二十)Spring Boot 整合 Redis

在 Redis 出現之前,我們的快取框架各種各樣,有了 Redis ,快取方案基本上都統一了,關於 Redis,鬆哥之前有一個系列教程,尚不瞭解 Redis 的小夥伴可以參考這個教程: Redis 教程合集 使用 Java 操作 Redis 的方案很多,Jedis 是目前較為流行的一種方案,除了 Jedi

Spring Boot2.0系列教程合集、Spring Cloud系列教程合集、Spring Boot常見錯誤合集、Spring Cloud常見錯誤合集

以下內容結合實際專案和工作經驗整理的Spring Boot和Spring Cloud學習教程和一些常見錯誤,希望能幫助到剛學習到童鞋,學習過程遇到問題評論回覆,第一時間會回覆!   Spring Boot2.0系列教程合集 1、Spring Boot2.0系列教程之idea下新

Spring Boot2 系列教程(一)純 Java 搭建 SSM 專案

在 Spring Boot 專案中,正常來說是不存在 XML 配置,這是因為 Spring Boot 不推薦使用 XML ,注意,並非不支援,Spring Boot 推薦開發者使用 Java 配置來搭建框架,Spring Boot 中,大量的自動化配置都是通過 Java 配置來實現的,這一套實現方案,我們也可

Spring Boot2 系列教程(二)建立 Spring Boot 專案的三種方式

我最早是 2016 年底開始寫 Spring Boot 相關的部落格,當時使用的版本還是 1.4.x ,文章發表在 CSDN 上,閱讀量最大的一篇有 43W+,如下圖: 2017 年由於種種原因,就沒有再繼續更新 Spring Boot 相關的部落格了,2018年又去寫書了,也沒更新,現在 Spring

Spring Boot2 系列教程(三)理解 Spring Boot 專案的 parent

前面和大夥聊了 Spring Boot 專案的三種建立方式,這三種建立方式,無論是哪一種,建立成功後,pom.xml 座標檔案中都有如下一段引用: <parent> <groupId>org.springframework.boot</groupId> &l

Spring Boot2 系列教程(四)理解Spring Boot 配置檔案 application.properties

在 Spring Boot 中,配置檔案有兩種不同的格式,一個是 properties ,另一個是 yaml 。 雖然 properties 檔案比較常見,但是相對於 properties 而言,yaml 更加簡潔明瞭,而且使用的場景也更多,很多開源專案都是使用 yaml 進行配置(例如 Hexo)。除了簡潔

Spring Boot2 系列教程(五)Spring Boot的 yaml 配置

搞 Spring Boot 的小夥伴都知道,Spring Boot 中的配置檔案有兩種格式,properties 或者 yaml,一般情況下,兩者可以隨意使用,選擇自己順手的就行了,那麼這兩者完全一樣嗎?肯定不是啦!本文就來和大夥重點介紹下 yaml 配置,最後再來看看 yaml 和 properties 配

Spring Boot2 系列教程(七)理解自動化配置的原理

Spring Boot 中的自動化配置確實夠吸引人,甚至有人說 Spring Boot 讓 Java 又一次煥發了生機,這話雖然聽著有點誇張,但是不可否認的是,曾經臃腫繁瑣的 Spring 配置確實讓人感到頭大,而 Spring Boot 帶來的全新自動化配置,又確實緩解了這個問題。 你要是問這個自動化配置是

Spring Boot2 系列教程(八)Spring Boot 配置 Https

https 現在已經越來越普及了,特別是做一些小程式或者公眾號開發的時候,https 基本上都是剛需了。 不過一個 https 證書還是挺費錢的,個人開發者可以在各個雲服務提供商那裡申請一個免費的證書。我印象中有效期一年,可以申請 20 個。 今天要和大家聊的是在 Spring Boot 專案中,如何開啟 h

Spring Boot2 系列教程(九)Spring Boot 整合 Thymeleaf

雖然現在慢慢在流行前後端分離開發,但是據鬆哥所瞭解到的,還是有一些公司在做前後端不分的開發,而在前後端不分的開發中,我們就會需要後端頁面模板(實際上,即使前後端分離,也會在一些場景下需要使用頁面模板,例如郵件傳送模板)。 早期的 Spring Boot 中還支援使用 Velocity 作為頁面模板,現在的