看大佬徒手擼一個 Starter,揭開 Starter 的神祕面紗!

作者 l江南一點雨

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


核心知識

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

看大佬徒手擼一個 Starter,揭開 Starter 的神秘面紗!

定義自己的 Starter

定義

所謂的 Starter ,其實就是一個普通的 Maven 項目,因此我們自定義 Starter ,需要首先創建一個普通的 Maven 項目,創建完成後,添加 Starter 的自動化配置類即可,如下:



 org.springframework.boot
 spring-boot-autoconfigure
 2.1.4.RELEASE


配置完成後,我們首先創建一個 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 中的值注入進去。

看大佬徒手擼一個 Starter,揭開 Starter 的神秘面紗!

做完這一步之後,我們的自動化配置類就算是完成了,接下來還需要一個 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,揭開 Starter 的神秘面紗!

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



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


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

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

看大佬徒手擼一個 Starter,揭開 Starter 的神秘面紗!

本地安裝

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

看大佬徒手擼一個 Starter,揭開 Starter 的神秘面紗!

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

看大佬徒手擼一個 Starter,揭開 Starter 的神秘面紗!

使用 Starter

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



 org.javaboy
 mystarter
 1.0-SNAPSHOT


此時我們引入了上面自定義的 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 的神秘面紗!

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

看大佬徒手擼一個 Starter,揭開 Starter 的神秘面紗!

今天就到這裡啦,喜歡編程的小夥伴可以關注我哦!有學習方面的問題可以私信回覆:學習!


分享到:


相關文章: