SpringBoot自定義starter操作
自定義Starter
1.Starter介紹
Starter場景啟動器是Spring Boot中一種非常重要的機制,它將繁瑣的配置統一整合到stater中,我們只需要通過在Maven將starter的依賴匯入專案,SpringBoot 就能自動掃描並載入相應的預設配置。starter的出現簡化了開發人員的工作量,從繁瑣的框架配置中解救出來,讓更多的時間專注在業務邏輯的開發,提高了開發效率。
2.命名規範
SpringBoot 提供的 starter 以 spring-boot-starter-xxx 的形式命名。為了與 SpringBoot 生態提供的 starter 進行區分,官方建議第三方開發者或技術(例如 Druid、Mybatis 等等)廠商自定義的 starter 使用 xxx-spring-boot-starter 的形式命名,例如 mybatis-spring-boot-starter、druid-spring-boot-starter 等等。
3.模組規範
Spring Boot 官方建議我們在自定義 starter 時,建立兩個 Module :autoConfigure Module(SpringBoot模組) 和 starter Module(Maven 模組),其中 starter Module 依賴於 autoConfigure Module。當然,這只是 Spring Boot 官方的建議,並不是硬性規定,若不需要自動配置程式碼和依賴專案分離,我們也可以將它們組合到同一個 Module 裡。
4.自定義Starter
1)starter啟動原理
- starter-pom引入 autoconfigure 包
- autoconfigure包中配置使用 META-INF/spring.factories 中 EnableAutoConfiguration 的值,使得專案啟動載入指定的自動配置類
- 編寫自動配置類 xxxAutoConfiguration -> xxxxProperties
-
@Configuration //配置類
-
@ConditionalOnMissingBean //條件裝配
-
@EnableConfigurationProperties(xxxProperties.class) //開啟屬性繫結功能(在配置檔案中修改值)+將繫結類xxxProperties加入容器
-
@Bean //生成元件
-
......
引入starter --- xxxAutoConfiguration --- 容器中放入元件 ---- 繫結xxxProperties ---- 配置項修改
5.自定義starter具體實操
(1)建立一個名為 spring-boot-customer-starter 空工程,工程下面新建兩個模組
1)hello-spring-boot-starter(場景啟動器,普通Maven工程);
2)hello-spring-boot-starter-autoconfigure(自動配置包,需用用到Spring Initializr建立的Maven工程);
3)hello-spring-boot-starter無需編寫什麼程式碼,只需讓該工程引入hello-spring-boot-starter-autoconfigure依賴
hello-spring-boot-starter 的 pom.xml 如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.liang</groupId> <artifactId>hello-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version>
<!--引入 hello-spring-boot-starter-autoconfigure 依賴 --> <dependencies> <dependency> <groupId>com.liang</groupId> <artifactId>hello-spring-boot-starter-autoconfigure</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project>
hello-spring-boot-starter-autoconfigure的 pom.xml 如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.liang</groupId> <artifactId>hello-spring-boot-starter-autoconfigure</artifactId> <version>0.0.1-SNAPSHOT</version> <name>hello-spring-boot-starter-autoconfigure</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies> </project>
(2)建立hello-spring-boot-starter-autoconfigure中的整個目錄
(3)定義Properties類
在com.liang.hello.bean包下建立一個實體類:HelloProperties,通過它來對映配置資訊。
package com.liang.hello.bean; import org.springframework.boot.context.properties.ConfigurationProperties; /** * @ConfigurationProperties("hello")是springboot提供讀取配置檔案的一個註解 * 1)讓當前類的屬性和配置檔案中以 hello開頭的配置進行繫結 * 2)以 hello為字首在配置檔案中讀取/修改當前類中的屬性值 */ @ConfigurationProperties("hello") public class HelloProperties { private String prefix; private String suffix; public String getPrefix() { return prefix; } public void setPrefix(String prefix) { this.prefix = prefix; } public String getSuffix() { return suffix; } public void setSuffix(String suffix) { this.suffix = suffix; } }
(4)定義Service類
在com.liang.hello.service包下建立一個HelloService類:實現具體業務功能。
package com.liang.hello.service; import com.liang.hello.bean.HelloProperties; import org.springframework.beans.factory.annotation.Autowired; /** * 預設不要放在容器中 */ public class HelloService { /** * @Autowired:自動注入屬性 * 在bean中的屬性上通過@Autowired實現自定義bean型別的屬性注入 * 使用是對應的bean必須被spring管理,即手動配置了bean或者在類上添加了@Component註解 * DI:就是注入功能,通俗的說就是給IOC創建出來的物件屬性賦值 */ @Autowired private HelloProperties helloProperties; //sayHello(String userName)方法 public String sayHello(String userName) { return helloProperties.getPrefix()+": "+userName+">> "+helloProperties.getSuffix(); } }
(5)定義自動配置類
在com.liang.hello.autoConfig包下建立一個HelloAutoConfiguration配置類。
package com.liang.hello.autoConfig; import com.liang.hello.bean.HelloProperties; import com.liang.hello.service.HelloService; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration //標識配置類 @EnableConfigurationProperties(HelloProperties.class)//開啟屬性繫結功能+預設將HelloProperties放在容器中 public class HelloAutoConfiguration { /** * @Bean註解用於告訴方法,產生一個Bean物件,然後這個Bean物件交給Spring管理。 * 產生這個Bean物件的方法Spring只會呼叫一次,隨後這個Spring將會將這個Bean物件放在自己的IOC容器中; * * @ConditionalOnMissingBean(HelloService.class) * 條件裝配:容器中沒有HelloService這個類時標註的方法才生效 / 建立一個HelloService類 */ @Bean @ConditionalOnMissingBean(HelloService.class) public HelloService helloService() { HelloService helloService = new HelloService(); return helloService; } }
(6)建立spring.factories檔案
1)Spring Factories機制是Spring Boot中一種服務發現機制,這種機制與Java SPI類似。
2)Spring Boot會自動掃描所有Jat包類路徑下META-INF/spring.factories檔案,並讀取其中的內容,進行例項化。這種機制也是Spring Boot Starter的基礎。
3)在helllo-spring-boot-starter-autoconfigure 的類路徑下(resources )中建立一個 META-INF 資料夾,並在 META-INF 資料夾中建立一個 spring.factories 檔案,並新增如下配置
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.liang.hello.autoConfig.HelloAutoConfiguration
4)注意:在spring.factories中顯示指定這些配置類的目錄,注意“,”後不要有空格之類的符號,就只寫該類的全路徑,不然會出現無法找到此bean的錯誤。
(7)構建starter
利用maven外掛將兩個工程打包到本地倉庫中。
1)自定義的本地倉庫目錄
2)將寫好的專案打包到本地倉庫中
最後自定義的starter構建成功!
總結使用:引入starter --- xxxAutoConfiguration --- 容器中放入元件 ---- 繫結xxxProperties ---- 配置項修改
總結自定義:
a.建立一個空工程,在裡面建立xxx-spring-boot-starter工程+建立 xxx-spring-boot-starter-autoConfigure工程;
b.在xxx-spring-boot-starter工程中引入xxx-spring-boot-starter-autoConfigure工程的依賴;
c.建立xxxAutoConfiguration,開啟自動屬性繫結功能(繫結xxxProperties),裡面新增需要元件;
d.在 xxx-spring-boot-starter-autoConfigure工程的 resources 包下建立META-INF/spring.factories檔案,裡面加入自動配置類的類路徑;
e.分別對兩個工程進行clean+install操作,將自定義的starter編譯並打包到本地倉庫,注意時刻保持最新狀態。
補充:maven的install可以將專案本身編譯並打包到本地倉庫,這樣其他專案引用本專案的jar包時不用去私服上下載jar包,直接從本地就可以拿到剛剛編譯打包好的專案的jar包,很靈活,避免每次都需要重新往私服釋出jar包的痛苦。
6、建立一個測試專案,引入自定義的starter依賴使用
(1)用Spring Initializr建立名為hello-spring-boot-starter-test工程,引入hello-spring-boot-starter依賴+spring web依賴測試
<dependency> <groupId>com.liang</groupId> <artifactId>hello-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
(2)建立配置檔案application.yaml,修改相應的屬性配置項
(3)定義Controller
在com.liang.hello.controller包下建立一個HelloController類:
package com.liang.hello.controller; import com.liang.hello.service.HelloService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController //=@Controller+@ResponseBody public class HelloController { @Autowired HelloService helloService; @GetMapping("/hello") //處理get請求方式的/hello請求路徑 public String sayHello() //處理方法 { String s = helloService.sayHello("阿嬌"); return s; } }
(4)執行
執行成功!自定義starter有效。