Spring Boot Starter 封裝的實(shí)現(xiàn)示例
一、為什么要封裝Starter?
在企業(yè)級(jí)開(kāi)發(fā)中,我們經(jīng)常需要將通用能力(如鑒權(quán)、日志、分布式鎖等)抽象為可復(fù)用的組件。Spring Boot Starter 的封裝能帶來(lái)三大核心優(yōu)勢(shì):
- ?配置統(tǒng)一管理? - 通過(guò)
application.properties實(shí)現(xiàn)“開(kāi)箱即用”,避免重復(fù)配置 - ?依賴自動(dòng)裝配? - 按需加載Bean,解決傳統(tǒng)組件依賴復(fù)雜的問(wèn)題
- ?版本統(tǒng)一控制? - 在父POM中管理依賴版本,規(guī)避兼容性風(fēng)險(xiǎn)
?舉個(gè)實(shí)際痛點(diǎn)?:
傳統(tǒng)JWT工具類需要每個(gè)項(xiàng)目手動(dòng)配置密鑰、過(guò)期時(shí)間等參數(shù),而通過(guò)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)入其他模塊下,其他模塊下沒(méi)有配置jwt屬性時(shí),使用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)自動(dòng)配置類
@Configuration
@EnableConfigurationProperties(JwtProperties.class)
@PropertySource("classpath:/config/jwt-default.properties")
@ConditionalOnClass(Jwts.class) // 當(dāng)JJWT存在時(shí)生效
@ConditionalOnProperty(prefix = "jwt", name = "enabled", matchIfMissing = true)
public class JwtAutoConfiguration {
@Bean
@ConditionalOnMissingBean // 用戶未自定義時(shí)生效
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. 注冊(cè)自動(dòng)配置
在 resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中寫入:
com.example.jwt.config.JwtAutoConfiguration
注意: 此注冊(cè)自動(dòng)配置為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小時(shí)
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),對(duì)于Starter導(dǎo)入其他模塊時(shí),其他模塊下的配置文件沒(méi)有配置Starter所需的配置時(shí),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)先級(jí)的原因:
Spring Boot的配置加載遵循特定優(yōu)先級(jí),后加載的配置會(huì)覆蓋先加載的。
如果其他模塊的配置文件中定義了同名屬性,會(huì)覆蓋Starter的默認(rèn)配置。
若模塊未顯式配置屬性,但Starter的默認(rèn)值未生效,需檢查Starter的默認(rèn)值設(shè)置方式:
出現(xiàn)此問(wèn)題就需要使用到 @PropertySource 注解,就如上示例使用方法一致。
四、配置加載優(yōu)先級(jí)解密
當(dāng)自定義配置與Starter默認(rèn)配置沖突時(shí),Spring Boot按以下優(yōu)先級(jí)處理(從高到低):
- ?命令行參數(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é)
?避免過(guò)度設(shè)計(jì)?
首版只需實(shí)現(xiàn)核心功能,迭代中逐步添加如Redis令牌黑名單等高級(jí)特性?防御性編程?
- 對(duì)密鑰進(jìn)行非空校驗(yàn):
Assert.hasText(properties.getKey(), "JWT密鑰不能為空") - Token解析增加空值判斷
- 對(duì)密鑰進(jìn)行非空校驗(yàn):
現(xiàn)在已經(jīng)可以舉一反三學(xué)會(huì)封裝其他的啦!
六、踩坑警示錄
?典型問(wèn)題1?:Bean注入沖突
?? ?現(xiàn)象?:?jiǎn)?dòng)報(bào) No qualifying bean of type 'JwtUtil'
? ?解決方案?:檢查是否誤加了 @Component 注解,應(yīng)通過(guò)自動(dòng)配置類創(chuàng)建Bean
?典型問(wèn)題2?:配置未生效
?? ?現(xiàn)象?:修改 application.yml 后仍使用默認(rèn)值
? ?排查步驟?:
- 檢查配置項(xiàng)命名是否符合
kebab-case(如access-token-ttl) - 確認(rèn)配置路徑是否被更高優(yōu)先級(jí)的源覆蓋
?討論話題?:你在封裝Starter時(shí)遇到過(guò)哪些棘手問(wèn)題?歡迎在評(píng)論區(qū)分享經(jīng)驗(yàn)給小nuo!
到此這篇關(guān)于Spring Boot Starter 封裝的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Spring Boot Starter 封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
WebUploader客戶端批量上傳圖片 后臺(tái)使用springMVC
這篇文章主要為大家詳細(xì)介紹了WebUploader客戶端批量上傳圖片,后臺(tái)使用springMVC接收實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09
springboot項(xiàng)目啟動(dòng),但是訪問(wèn)報(bào)404錯(cuò)誤的問(wèn)題
這篇文章主要介紹了springboot項(xiàng)目啟動(dòng),但是訪問(wèn)報(bào)404錯(cuò)誤的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Java?switch?case語(yǔ)句的用法及常見(jiàn)問(wèn)題
這篇文章主要介紹了Java?switch?case語(yǔ)句的用法及常見(jiàn)問(wèn)題,Java中的switch語(yǔ)句是一種多分支選擇結(jié)構(gòu),用于替代多個(gè)if...elseif的情況,它根據(jù)某個(gè)變量的值,執(zhí)行匹配分支中的代碼塊,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-04-04
出現(xiàn)SLF4J:?Failed?to?load?class?“org.slf4j.impl.StaticLog
本文主要介紹了出現(xiàn)SLF4J:?Failed?to?load?class?“org.slf4j.impl.StaticLoggerBinder“.的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
JVM入門之類加載與字節(jié)碼技術(shù)(類加載與類的加載器)
Java字節(jié)碼增強(qiáng)指的是在Java字節(jié)碼生成之后,對(duì)其進(jìn)行修改,增強(qiáng)其功能,這種方式相當(dāng)于對(duì)應(yīng)用程序的二進(jìn)制文件進(jìn)行修改。Java字節(jié)碼增強(qiáng)主要是為了減少冗余代碼,提高性能等2021-06-06
IDEA無(wú)法識(shí)別相關(guān)module模塊問(wèn)題的解決過(guò)程
這篇文章主要給大家介紹了關(guān)于IDEA無(wú)法識(shí)別相關(guān)module模塊問(wèn)題的解決過(guò)程,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用IDEA具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
SpringBoot配置HTTPS及開(kāi)發(fā)調(diào)試的操作方法
在實(shí)際開(kāi)發(fā)過(guò)程中,如果后端需要啟用https訪問(wèn),通常項(xiàng)目啟動(dòng)后配置nginx代理再配置https,前端調(diào)用時(shí)高版本的chrome還會(huì)因?yàn)樽C書未信任導(dǎo)致調(diào)用失敗,通過(guò)摸索整理一套開(kāi)發(fā)調(diào)試下的https方案,下面給大家分享SpringBoot配置HTTPS及開(kāi)發(fā)調(diào)試,感興趣的朋友跟隨小編一起看看吧2024-05-05

