Spring Boot Starter 封裝的實(shí)現(xiàn)示例
一、為什么要封裝Starter?
在企業(yè)級開發(fā)中,我們經(jīng)常需要將通用能力(如鑒權(quán)、日志、分布式鎖等)抽象為可復(fù)用的組件。Spring Boot Starter 的封裝能帶來三大核心優(yōu)勢:
- ?配置統(tǒng)一管理? - 通過
application.properties實(shí)現(xiàn)“開箱即用”,避免重復(fù)配置 - ?依賴自動裝配? - 按需加載Bean,解決傳統(tǒng)組件依賴復(fù)雜的問題
- ?版本統(tǒng)一控制? - 在父POM中管理依賴版本,規(guī)避兼容性風(fēng)險
?舉個實(shí)際痛點(diǎn)?:
傳統(tǒng)JWT工具類需要每個項(xiàng)目手動配置密鑰、過期時間等參數(shù),而通過Starter封裝后,只需引入依賴即可直接注入預(yù)配置的Bean。
二、手把手實(shí)現(xiàn)JWT Starter
1. 創(chuàng)建模塊 & 初始化依賴
按Spring官方規(guī)范命名模塊:jwt-spring-boot-starter
<!-- 核心依賴 -->
<dependencies>
<!-- JJWT 相關(guān) -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<!-- 配置元數(shù)據(jù)生成 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2. 創(chuàng)建配置文件 & Properties類
創(chuàng)建 resources/config/jwt-default.properties
此文件用于在Starter導(dǎo)入其他模塊下,其他模塊下沒有配置jwt屬性時,使用Starter內(nèi)部的配置文件屬性。
jwt.key=default_secret_key jwt.access_token_ttl=300000 jwt.refresh_token_ttl=604800000
創(chuàng)建 JwtProperties 類:
// main/java/.../config
@Data
@Configuration
@ConfigurationProperties(prefix = "jwt")
public class JwtProperties {
private String key;
private long accessTokenTtl;
private long refreshTokenTtl;
}
3. 實(shí)現(xiàn)自動配置類
@Configuration
@EnableConfigurationProperties(JwtProperties.class)
@PropertySource("classpath:/config/jwt-default.properties")
@ConditionalOnClass(Jwts.class) // 當(dāng)JJWT存在時生效
@ConditionalOnProperty(prefix = "jwt", name = "enabled", matchIfMissing = true)
public class JwtAutoConfiguration {
@Bean
@ConditionalOnMissingBean // 用戶未自定義時生效
public JwtUtil jwtUtil(JwtProperties properties) {
return new JwtUtil(properties);
}
}
4. 編寫JWT核心工具類
public class JwtUtil {
private final JwtProperties properties;
public JwtUtil(JwtProperties properties) {
this.properties = properties;
}
// 生成AccessToken(示例代碼)
public String createAccessToken(ClaimDTO claims) {
return Jwts.builder()
.setClaims(convertToMap(claims))
.setExpiration(new Date(System.currentTimeMillis() + properties.getAccessTokenTtl()))
.signWith(Keys.hmacShaKeyFor(properties.getKey().getBytes()))
.compact();
}
// Token校驗(yàn)(返回枚舉更規(guī)范)
public TokenStatus validateToken(String token) {
try {
parseToken(token);
return TokenStatus.VALID;
} catch (ExpiredJwtException e) {
return TokenStatus.EXPIRED;
}
// ... 其他異常處理
}
}
5. 注冊自動配置
在 resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中寫入:
com.example.jwt.config.JwtAutoConfiguration
注意: 此注冊自動配置為Spring Boot 3.x 版本。
三、在項(xiàng)目中集成Starter
1. 引入依賴
<dependency>
<groupId>com.example</groupId>
<artifactId>jwt-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
2. 自定義配置(可選)
在 application.yml 中覆蓋默認(rèn)值:
jwt: key: your_secure_key_here access-token-ttl: 3600000 # 1小時
3. 直接注入使用
@RestController
public class AuthController {
private final JwtUtil jwtUtil;
// 構(gòu)造器注入
public AuthController(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}
@PostMapping("/login")
public String login(@RequestBody User user) {
// ... 驗(yàn)證邏輯
return jwtUtil.createAccessToken(user);
}
}
4. 注意事項(xiàng)
小nuo發(fā)現(xiàn),對于Starter導(dǎo)入其他模塊時,其他模塊下的配置文件沒有配置Starter所需的配置時,Starter的默認(rèn)配置丟失,解決方案:
在 jwtProperties 類中直接設(shè)置默認(rèn)值
@ConfigurationProperties(prefix = "jwt")
public class JwtProperties {
// 直接設(shè)置字段默認(rèn)值
private String secretKey = "default-secret";
private long expiration = 3600L;
}
使用 @PropertySource 從而確保使用Starter內(nèi)部配置文件 因?yàn)?strong>Spring Boot配置加載優(yōu)先級的原因:
Spring Boot的配置加載遵循特定優(yōu)先級,后加載的配置會覆蓋先加載的。
如果其他模塊的配置文件中定義了同名屬性,會覆蓋Starter的默認(rèn)配置。
若模塊未顯式配置屬性,但Starter的默認(rèn)值未生效,需檢查Starter的默認(rèn)值設(shè)置方式:
出現(xiàn)此問題就需要使用到 @PropertySource 注解,就如上示例使用方法一致。
四、配置加載優(yōu)先級解密
當(dāng)自定義配置與Starter默認(rèn)配置沖突時,Spring Boot按以下優(yōu)先級處理(從高到低):
- ?命令行參數(shù)?
java -jar app.jar --jwt.key=cli_key - ?應(yīng)用配置文件?
application.properties>application.yml - ?Starter默認(rèn)配置?
jwt-default.properties - ?代碼默認(rèn)值?
JwtProperties類中的字段初始值
五、封裝經(jīng)驗(yàn)總結(jié)
?避免過度設(shè)計(jì)?
首版只需實(shí)現(xiàn)核心功能,迭代中逐步添加如Redis令牌黑名單等高級特性?防御性編程?
- 對密鑰進(jìn)行非空校驗(yàn):
Assert.hasText(properties.getKey(), "JWT密鑰不能為空") - Token解析增加空值判斷
- 對密鑰進(jìn)行非空校驗(yàn):
現(xiàn)在已經(jīng)可以舉一反三學(xué)會封裝其他的啦!
六、踩坑警示錄
?典型問題1?:Bean注入沖突
?? ?現(xiàn)象?:啟動報 No qualifying bean of type 'JwtUtil'
? ?解決方案?:檢查是否誤加了 @Component 注解,應(yīng)通過自動配置類創(chuàng)建Bean
?典型問題2?:配置未生效
?? ?現(xiàn)象?:修改 application.yml 后仍使用默認(rèn)值
? ?排查步驟?:
- 檢查配置項(xiàng)命名是否符合
kebab-case(如access-token-ttl) - 確認(rèn)配置路徑是否被更高優(yōu)先級的源覆蓋
?討論話題?:你在封裝Starter時遇到過哪些棘手問題?歡迎在評論區(qū)分享經(jīng)驗(yàn)給小nuo!
到此這篇關(guān)于Spring Boot Starter 封裝的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Spring Boot Starter 封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
WebUploader客戶端批量上傳圖片 后臺使用springMVC
這篇文章主要為大家詳細(xì)介紹了WebUploader客戶端批量上傳圖片,后臺使用springMVC接收實(shí)例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-09-09
springboot項(xiàng)目啟動,但是訪問報404錯誤的問題
這篇文章主要介紹了springboot項(xiàng)目啟動,但是訪問報404錯誤的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
出現(xiàn)SLF4J:?Failed?to?load?class?“org.slf4j.impl.StaticLog
本文主要介紹了出現(xiàn)SLF4J:?Failed?to?load?class?“org.slf4j.impl.StaticLoggerBinder“.的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
JVM入門之類加載與字節(jié)碼技術(shù)(類加載與類的加載器)
Java字節(jié)碼增強(qiáng)指的是在Java字節(jié)碼生成之后,對其進(jìn)行修改,增強(qiáng)其功能,這種方式相當(dāng)于對應(yīng)用程序的二進(jìn)制文件進(jìn)行修改。Java字節(jié)碼增強(qiáng)主要是為了減少冗余代碼,提高性能等2021-06-06
IDEA無法識別相關(guān)module模塊問題的解決過程
這篇文章主要給大家介紹了關(guān)于IDEA無法識別相關(guān)module模塊問題的解決過程,文中通過圖文介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用IDEA具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07
SpringBoot配置HTTPS及開發(fā)調(diào)試的操作方法
在實(shí)際開發(fā)過程中,如果后端需要啟用https訪問,通常項(xiàng)目啟動后配置nginx代理再配置https,前端調(diào)用時高版本的chrome還會因?yàn)樽C書未信任導(dǎo)致調(diào)用失敗,通過摸索整理一套開發(fā)調(diào)試下的https方案,下面給大家分享SpringBoot配置HTTPS及開發(fā)調(diào)試,感興趣的朋友跟隨小編一起看看吧2024-05-05

