前言
前幾個月和隔壁組的老王閒聊,他說專案的供應商離職率居高不下,最近還有開發剛接手ESB訂閱釋出介面才兩週就提出離職,而他能做的就只有苦笑和默默地接過這個爛攤子了。
而然幸福的家庭總是相似的,而不幸的我卻因業務變革走上了和老王一樣的道路。單單是介面的開發居然能迫使一位開發毅然決然地離職,我既不相信是人性的扭曲,更不信是道德的淪喪。
拋開這個富有色彩的故事而言,我發現原來的專案存在如下問題:
- 沒有使用任何現代依賴管理和構建工具(如Maven, Gradle),直接把所依賴的Jar包存放在專案目錄下的lib目錄中,日積月累導致lib目錄下存放大量無用Jar包;
- 沒有使用程式碼版本管理工具管理程式碼;
- 技術文件欠缺,全靠師傅帶徒弟的方式傳授框架使用方式和開發流程;
- 機械性配置項多,而後來的開發人員大多隻能依葫蘆畫瓢新增配置,既容易出錯同時又增加問題排查的難度。
針對前兩個問題,我們只需梳理出必須的依賴項並加入Maven或Gradle管理,然後託管到Git即可。
而後兩者則可以通過spring-boot-starter將必選依賴項和配置統一管理,並附上相關技術文件;然後通過模板模式和註解簡化開發流程,提供Demo降低入門難度。
最後就可以把具體的業務功能開發交給供應商處理,我們專心做好過程管理和驗收即可。
本文將著重分享spring-boot-starter開發的事項,請坐好扶穩!
命名規範
在自定義starter前我們總要思考如何命名我們的starter,而官方提供如下的命名規範:
- 官方的starter以spring-boot-starter作為字首命名專案
如:spring-boot-starter-web - 非官方的則以spring-boot-starter作為字尾命名專案
如:mybatis-spring-boot-starter
專案結構
通過Spring Initializr或Spring Boot CLI建立專案結構後,將pom.xml的相關專案修改為如下內容
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifacId>
<version>2.3.1.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 下面為自定義Starter的依賴項 -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
在starter中我們會定義SpringBean的註冊配置和屬性配置,如ESB訂閱服務的配置專案為
@Configuration
@EnableConfigurationProperties({EsbServerProperties.class})
public class EsbServerConfiguration {
@Bean
public SpringBus springBus(){
return new SpringBus();
}
@Bean
public LoggingFeature loggingFeature(){
return new LoggingFeature();
}
@Bean
public List<JMSConfigFeature> jmsConfigFeatures(EsbServerProperties props) throws JMSException {
List<JMSConfigFeature> features = new ArrayList<>();
/**
* 這裡會使用EsbServerProperties的屬性構建Bean例項
*/
return features;
}
}
屬性配置項
// 從application.yml等配置檔案中讀取並繫結esb.server.destination等屬性值
@Data
@ConfigurationProperties("esb.server")
public class EsbServerProperties {
String destination;
int currConsumers = 1;
String channel;
int ccsid = 1205;
int transportType = 1;
List<String> connectionNameLists;
boolean replyError = false;
String replySuccessText = "Success";
String replyErrorText = "Failure";
}
到這裡我們已經完成一個基本的starter的功能
- 通過
@ConfigurationProperties
定義該starter註冊bean時需要的屬性集合 - 通過
@Configuration
定義該starter註冊的bean
但引用該starter的專案要如何啟用配置呢?其實有兩種方式,分別為手動和自動,其中我們會著重講解自動啟用配置。
手動啟用配置
所謂手動啟用配置其實就是在SpringBoot入口類上新增啟用配置用的自定義註解,針對上面的EsbServerConfiguration我們可以自定義EnableESBSrv註解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({EsbServerConfiguration.class})
public @interface EnableEsbSrv {
}
然後入口類的@SpringBootApplication
註解前後新增@EnableEsbSrv
即可。
讓人省心省力的自動啟用配置
自動啟用配置即只需在pom.xml中引入所依賴的starter,然後啟用應用即可自動啟用該starter的@Configuration
所註解的類從而註冊Bean和讀取屬性配置。
而這一切都是由AutoConfigurationImportSelector
來操刀,而我們可以通過@EnableAutoConfiguration
或@SpringBootApplication
等例項化AutoConfigurationImportSelector
類,配合菜譜resources/META-INF/spring.factories實現自動化配置的功能。
具體手法就是:將EsbServerConfiguration的全限類名稱寫在resources/META-INF/spring.factories的org.springframework.boot.autoconfigure.EnableAutoConfiguration
下, 若存在多個則用逗號分隔。
org.springframework.boot.autoconfigure.EnableAutoConfiguration = \
com.john.starter.EsbServerConfiguration,\
com.john.starter.OtherConfiguration
好與更好——整合IDE智慧提示
應用啟動時會將application.yml中對應的配置項繫結到@ConfigurationProperties
標註的類例項上,那麼對於應用開發人員而言日常工作就是修改application.yml的配置項。但IDE又缺少配置項的智慧提示,那就很低效了。幸虧Spring Boot早就為我們提供好解決方案,分為手工和自動兩種。為了效率當然是可以自動就不用手動的了。
Starter專案的工作
- 引入spring-boot-configuration-processor依賴項;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
- 若src/resources/META-INF/spring-configuration-metadata.json不存在,那麼執行
mvn compile
時會生成target/classes/META-INF/spring-configuration-metadata.json; - 複製target/classes/META-INF/spring-configuration-metadata.json到src/resources/META-INF/spring-configuration-metadata.json即可。
業務系統專案的工作
- 引入spring-boot-configuration-processor依賴項;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
- IDEA安裝Spring Assistant外掛,並啟用Enable annotation processing(勾選 Settings/Build, Execution & Deployment/Compiles/Annotation Processors/Enable annotation processing)。
總結
spring-boot-starter非常適合用於團隊的技術積累和沉澱,不過想恰到好處地應用起來,不僅要需要深入Spring內部原理還要梳理清楚業務邏輯。後續我們再深入探討Spring核心的事情吧!
轉載請註明來自:https://www.cnblogs.com/fsjohnhuang/p/13956039.html —— ^_^肥仔John