1、前言
最近公司在做一個(gè)中臺(tái)項(xiàng)目,涉及到公司內(nèi)部系統(tǒng)調(diào)用准潭,考慮到每上馬一個(gè)項(xiàng)目都需要進(jìn)行客戶端接口開(kāi)發(fā)。本著對(duì)公司對(duì)項(xiàng)目對(duì)個(gè)人負(fù)責(zé)的態(tài)度域仇,為防止各項(xiàng)目重復(fù)性開(kāi)發(fā)刑然,且項(xiàng)目組因個(gè)人能力問(wèn)題,為降低代碼耦合暇务,強(qiáng)烈要求本次中臺(tái)項(xiàng)目對(duì)于公司內(nèi)各系統(tǒng)開(kāi)發(fā)各自的SDK泼掠,創(chuàng)建屬于各自的Spring Boot Starter
另外,我還有一個(gè)要求就是需要支持Apollo配置中心垦细,下面看看我們是怎么操作的吧择镇!文末有源碼地址哦!
2蝠检、項(xiàng)目結(jié)構(gòu)
一個(gè)完整的Spring Boot Starter可能包含了下面兩個(gè)模塊
-
autoconfigure
模塊包含了 auto-configuration 相關(guān)代碼. -
starter
模塊依賴autoconfigure
模塊沐鼠,且包含了其他通用的依賴項(xiàng) ,簡(jiǎn)單來(lái)說(shuō)就是它包含了使用該starter的一切叹谁。
注意:這兩個(gè)模塊不是必須的饲梭,可以合并成一個(gè)模塊,實(shí)際項(xiàng)目中我們就是采用合并的方式焰檩,但是本文還是按照兩個(gè)來(lái)介紹
下面看下我準(zhǔn)備的案例的結(jié)構(gòu):
fucking-great/
├── fg-spring-boot-autoconfigure
├── fg-spring-boot-sample
└── fg-spring-boot-starter
這里我們多新建了一個(gè)模塊叫fg-spring-boot-sample
主要是為了模仿實(shí)際項(xiàng)目依賴使用本次新建的starter而專門設(shè)計(jì)的單元測(cè)試模塊
3憔涉、命名規(guī)范
不要以spring-boot
開(kāi)頭來(lái)命名自定義的starter,官方支持的會(huì)使用此開(kāi)頭來(lái)命名析苫。假設(shè)你創(chuàng)建一個(gè)項(xiàng)目叫“FuckingGreat”(牛逼)兜叨,我還沒(méi)開(kāi)始干,看到名字就感覺(jué)起飛了衩侥。興奮的感覺(jué)自己要干一票大事情国旷,感覺(jué)走上了人生巔峰∶K溃咳咳.....回到正軌跪但,你可以定義autoconfigure
模塊叫fg-spring-boot-autoconfigure
,starter
模塊就叫做fg-spring-boot-starter
4峦萎、autoconfigure
模塊
autoconfigure
包含了啟動(dòng)庫(kù)的一切依賴屡久,它可能包含了參數(shù)配置的關(guān)鍵定義(例:@ConfigurationProperties)和任何回調(diào)接口忆首,以便未來(lái)可以自定義啟動(dòng)方式。
我們建議在autoconfigure
模塊添加如下依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
它可以幫助我們?cè)诰幾g打包starter后自動(dòng)生成元數(shù)據(jù)在META-INF/spring-autoconfigure-metadata.properties
目錄下被环,另外注意使用了標(biāo)簽<optional>true</optional>
用以幫助提升啟動(dòng)時(shí)間
如果我們想要?jiǎng)?chuàng)建額外的自定義的元數(shù)據(jù)糙及,我們可以添加如下依賴,當(dāng)然我們這里是要加的筛欢,經(jīng)過(guò)測(cè)試發(fā)現(xiàn)不加此依賴的話浸锨,在sample
模塊的application.propeties
輸入具體配置的時(shí)候IDE無(wú)法自動(dòng)提示。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
參考文檔: Generating Your Own Metadata
我們看一下本次介紹案例該模塊下有哪些代碼
├── autoconfigure
│ ├── FuckingGreatAutoConfiguration.java
│ └── FuckingGreatProperties.java
└── service
└── FuckingGreatService.java
4.1悴能、FuckingGreatProperties 類
它就是一個(gè)properties配置文件揣钦,用于接收自定義的屬性
package com.example.fg.autoconfigure;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author cattle - 稻草鳥(niǎo)人
* @date 2020/3/14 下午6:40
*/
@Data
@ConfigurationProperties(prefix = "com.example.fg")
public class FuckingGreatProperties {
/**
* input your name
*/
private String name;
}
4.2、FuckingGreatService 類
它是本案例starter提供具體服務(wù)的類漠酿,我們看下代碼
package com.example.fg.service;
import com.example.fg.autoconfigure.FuckingGreatProperties;
import lombok.AllArgsConstructor;
/**
* @author cattle - 稻草鳥(niǎo)人
* @date 2020/3/14 下午6:47
*/
@AllArgsConstructor
public class FuckingGreatService {
FuckingGreatProperties fuckingGreatProperties;
public String hello() {
return fuckingGreatProperties.getName();
}
}
4.3冯凹、FuckingGreatAutoConfiguration 類
它為我們初始化了一個(gè)服務(wù)bean
package com.example.fg.autoconfigure;
import com.example.fg.service.FuckingGreatService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* @author cattle - 稻草鳥(niǎo)人
* @date 2020/3/14 下午6:24
*/
@EnableConfigurationProperties(FuckingGreatProperties.class)
public class FuckingGreatAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public FuckingGreatService fuckingGreatService(FuckingGreatProperties fuckingGreatProperties) {
return new FuckingGreatService(fuckingGreatProperties);
}
}
4.4、spring.factories
在resources目錄下炒嘲,我們需要新建一個(gè)目錄叫META-INF的文件夾宇姚,然后在META-INF目錄下新建spring.factories文件,該文件內(nèi)容如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.fg.autoconfigure.FuckingGreatAutoConfiguration
5夫凸、starter
模塊
它就是個(gè)空模塊浑劳,它的唯一目的是提供使用庫(kù)所必需的依賴項(xiàng),本次案例它就依賴了autoconfigure
模塊而已
6夭拌、sample
模塊
首先我們創(chuàng)建了一個(gè)applicaiton.properties文件魔熏,內(nèi)容如下:
com.example.fg.name=cattle
然后我們寫的一個(gè)單元測(cè)試類:
package com.example.fg;
import com.example.fg.service.FuckingGreatService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class FuckingGreatApplicationTest {
@Autowired
FuckingGreatService fuckingGreatService;
@Test
public void test() {
String name = fuckingGreatService.hello();
assertEquals(name, "cattle");
}
}
7、Ctrip Apollo集成測(cè)試
這個(gè)也很簡(jiǎn)單啦鸽扁,搭建好Apollo之后蒜绽,修改sample
模塊下test/resources
目錄下的aplicaiton.properties
文件內(nèi)容如下:
#com.example.fg.name=cattle
app.id=100004458
apollo.autoUpdateInjectedSpringProperties=false
# Apollo Meta Server 地址
apollo.meta=http://xx.xx.xx.xx:8080
# 自定義本地配置文件緩存路徑
apollo.cacheDir=./cache
# 設(shè)置在應(yīng)用啟動(dòng)階段就加載 Apollo 配置
apollo.bootstrap.enabled=true
# 注入 application namespace
apollo.bootstrap.namespaces=application
然后在項(xiàng)目啟動(dòng)類上面增加注解@EnableApolloConfig
即可
8、源碼地址
https://github.com/cattles/fucking-great-autoconfigure.git