最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot @ConfigurationProperties + Validation實(shí)現(xiàn)啟動(dòng)期校驗(yàn)解決方案

 更新時(shí)間:2025年09月15日 10:50:47   作者:小明知意  
本文給大家介紹SpringBoot @ConfigurationProperties + Validation實(shí)現(xiàn)啟動(dòng)期校驗(yàn)解決方案,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

小明成長(zhǎng)記:@ConfigurationProperties+Validation實(shí)現(xiàn)啟動(dòng)期校驗(yàn)

事故回顧:周三下午 2 點(diǎn),監(jiān)控系統(tǒng)突然告警,某核心服務(wù)的錯(cuò)誤日志激增。小明和小伙伴們立刻被拉進(jìn)緊急會(huì)議。經(jīng)排查,發(fā)現(xiàn)錯(cuò)誤原因是:一個(gè)新上線的短信推送功能,其服務(wù)商API URL在線上環(huán)境的配置文件中完全缺失。導(dǎo)致RestTemplate在調(diào)用時(shí),注入的String類型的 URL 為null,最終在運(yùn)行時(shí)拋出了NullPointerException。

甩鍋現(xiàn)場(chǎng):

  • 部門老大:“這個(gè)功能測(cè)試環(huán)境不是好好的嗎?為什么線上掛了?誰負(fù)責(zé)的配置?”
  • 運(yùn)維同事:“部署流程都是自動(dòng)化的,配置是根據(jù)開發(fā)提供的清單來管理的。清單里沒寫這個(gè)新配置項(xiàng),我們當(dāng)然不知道要配。”
  • 小明(內(nèi)心OS):“完了,這個(gè)功能是我做的。我以為大家都會(huì)看代碼,知道要配這個(gè)……”

老大批示:
“小明,這次的問題根源是配置管理不規(guī)范。你立刻整改代碼,要讓程序在啟動(dòng)的時(shí)候自己告訴我們?nèi)绷耸裁磁渲?,而不是等到用戶用的時(shí)候才崩潰! 以后絕不允許再發(fā)生這種低級(jí)錯(cuò)誤!”

小明的任務(wù):
對(duì)代碼進(jìn)行改造,利用 @ConfigurationProperties 在應(yīng)用啟動(dòng)階段對(duì)關(guān)鍵參數(shù)進(jìn)行強(qiáng)校驗(yàn),避免配置缺失導(dǎo)致運(yùn)行時(shí)出錯(cuò)。

小明的改造方案:使用@ConfigurationProperties進(jìn)行啟動(dòng)期校驗(yàn)

小明決定采用 Spring Boot 官方推薦的 @ConfigurationProperties + Validation 方案。這樣,如果配置缺失或不符合規(guī)則,應(yīng)用將根本無法啟動(dòng),并在日志中明確打印出缺失的配置項(xiàng),運(yùn)維同學(xué)直接拿著錯(cuò)誤信息去補(bǔ)配置即可。

第一步:引入校驗(yàn)依賴

首先,他檢查了項(xiàng)目的 pom.xml,確保包含了 spring-boot-starter-validation 依賴。這是實(shí)現(xiàn)校驗(yàn)功能的基礎(chǔ)。

<!-- 如果使用的是 Spring Boot 2.3+ 版本,需要顯式引入 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

第二步:創(chuàng)建配置屬性類并添加校驗(yàn)規(guī)則

小明為短信服務(wù)創(chuàng)建了一個(gè)專門的配置屬性類,將所有相關(guān)的配置項(xiàng)集中管理。

package com.example.demo.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
/**
 * 短信服務(wù)配置
 * 使用 @Validated 注解開啟校驗(yàn)
 * 使用 @ConfigurationProperties 綁定前綴為 "sms" 的配置
 */
@Component
@Validated // 關(guān)鍵注解1:告訴Spring需要對(duì)此Bean進(jìn)行校驗(yàn)
@ConfigurationProperties(prefix = "sms") // 關(guān)鍵注解2:綁定配置前綴
public class SmsProperties {
    /**
     * 服務(wù)商API地址
     * 本次事故的罪魁禍?zhǔn)祝?
     * @NotBlank 確保該值不能為 null 或空字符串
     */
    @NotBlank(message = "【短信服務(wù)】關(guān)鍵配置 'sms.url' 未配置,請(qǐng)檢查配置文件!")
    private String url;
    /**
     * 授權(quán)密鑰
     */
    @NotBlank(message = "【短信服務(wù)】關(guān)鍵配置 'sms.secret-id' 未配置")
    private String secretId;
    /**
     * 操作密鑰
     */
    @NotBlank(message = "【短信服務(wù)】關(guān)鍵配置 'sms.secret-key' 未配置")
    private String secretKey;
    /**
     * 重試次數(shù)
     * @NotNull 確保數(shù)字類型的配置不為空
     * @Min 設(shè)置最小值
     */
    @NotNull(message = "【短信服務(wù)】配置 'sms.retry-times' 未配置")
    @Min(value = 0, message = "【短信服務(wù)】配置 'sms.retry-times' 的值不能小于0")
    private Integer retryTimes;
    /**
     * 是否啟用短信服務(wù)(生產(chǎn)環(huán)境才啟用,開發(fā)測(cè)試環(huán)境可能不啟用)
     * 這里使用了默認(rèn)值 false,即使不配置也不會(huì)報(bào)錯(cuò)
     */
    private Boolean enabled = false;
    // 標(biāo)準(zhǔn)的 Getter 和 Setter 方法必須存在,否則配置無法注入
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getSecretId() {
        return secretId;
    }
    public void setSecretId(String secretId) {
        this.secretId = secretId;
    }
    public String getSecretKey() {
        return secretKey;
    }
    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }
    public Integer getRetryTimes() {
        return retryTimes;
    }
    public void setRetryTimes(Integer retryTimes) {
        this.retryTimes = retryTimes;
    }
    public Boolean getEnabled() {
        return enabled;
    }
    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }
}

第三步:在業(yè)務(wù)代碼中注入使用

改造原來的代碼,不再直接使用 @Value 注入單個(gè)屬性,而是注入這個(gè)完整的配置 Bean。

package com.example.demo.service;
import com.example.demo.config.SmsProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SmsService {
    // 直接注入配置Bean
    private final SmsProperties smsProperties;
    @Autowired
    public SmsService(SmsProperties smsProperties) {
        this.smsProperties = smsProperties;
    }
    public void sendSms(String phoneNumber, String content) {
        // 使用配置
        if (Boolean.TRUE.equals(smsProperties.getEnabled())) {
            String targetUrl = smsProperties.getUrl(); // 這里拿到的url肯定是有效的
            String secretId = smsProperties.getSecretId();
            // ... 實(shí)際調(diào)用發(fā)送邏輯
            System.out.println("正在調(diào)用短信服務(wù): " + targetUrl);
        } else {
            System.out.println("短信服務(wù)未啟用,已忽略發(fā)送。");
        }
    }
}

第四步:準(zhǔn)備配置文件

錯(cuò)誤的配置 (application.yml) - 用于復(fù)現(xiàn)事故:

sms:
  # url: https://api.sms-service.com/send # 故意注釋掉,模擬遺忘配置
  secret-id: your_secret_id_here
  # secret-key: your_secret_key_here # 也注釋掉一個(gè)
  retry-times: -1 # 配置了一個(gè)非法的值

第五步:?jiǎn)?dòng)應(yīng)用,觀察效果

當(dāng)小明啟動(dòng)應(yīng)用時(shí),應(yīng)用根本無法啟動(dòng),控制臺(tái)會(huì)立即打印出如下非常清晰的錯(cuò)誤信息:

***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'sms' to com.example.demo.config.SmsProperties failed:
    Property: sms.url
    Value: null
    Reason: 【短信服務(wù)】關(guān)鍵配置 'sms.url' 未配置,請(qǐng)檢查配置文件!
    Property: sms.secret-key
    Value: null
    Reason: 【短信服務(wù)】關(guān)鍵配置 'sms.secret-key' 未配置
    Property: sms.retry-times
    Value: -1
    Reason: 【短信服務(wù)】配置 'sms.retry-times' 的值不能小于0
Action:
Update your application's configuration

改造后的成效

  • 啟動(dòng)即發(fā)現(xiàn):配置問題在應(yīng)用啟動(dòng)之初就被發(fā)現(xiàn),無法形成部署包,根本不會(huì)影響線上用戶。
  • 責(zé)任清晰:錯(cuò)誤信息極其明確,直接指出是哪個(gè)配置前綴(sms)下的哪個(gè)屬性(urlsecret-key)出了問題,以及原因。運(yùn)維同學(xué)無需再問開發(fā),直接看日志就能完成配置。
  • 溝通成本降低:開發(fā)人員只需提供配置屬性類的定義(可以作為文檔),運(yùn)維按圖索驥即可。message 屬性中的中文提示更是大大提升了溝通效率。
  • 代碼更健壯:配置集中管理,結(jié)構(gòu)清晰,避免了散落的 @Value,易于維護(hù)和擴(kuò)展。

小明將改造后的代碼提交上線后,部門老大對(duì)此表示了肯定。從此,團(tuán)隊(duì)的配置管理流程變得更加規(guī)范,再也沒有發(fā)生過因配置缺失導(dǎo)致的線上故障。

到此這篇關(guān)于SpringBoot @ConfigurationProperties + Validation實(shí)現(xiàn)啟動(dòng)期校驗(yàn)解決方案的文章就介紹到這了,更多相關(guān)SpringBoot @ConfigurationProperties Validation啟動(dòng)校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot利用限速器RateLimiter實(shí)現(xiàn)單機(jī)限流的示例代碼

    SpringBoot利用限速器RateLimiter實(shí)現(xiàn)單機(jī)限流的示例代碼

    本文主要介紹了SpringBoot利用限速器RateLimiter實(shí)現(xiàn)單機(jī)限流的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • SpringBoot返回前端Long型丟失精度后兩位變成00的解決

    SpringBoot返回前端Long型丟失精度后兩位變成00的解決

    在后端開發(fā)中,當(dāng)Long類型的ID超過19位時(shí),前端JavaScript可能會(huì)出現(xiàn)精度問題,導(dǎo)致最后兩位變成00,本文提出了三種解決方案:將ID轉(zhuǎn)換為字符串、使用@JsonSerialize注解和使用@JsonFormat注解,通過這些方法,可以確保ID在前后端傳輸過程中不會(huì)發(fā)生精度丟失
    2026-01-01
  • 詳解Java synchronized關(guān)鍵字的用法

    詳解Java synchronized關(guān)鍵字的用法

    在多線程編程中常常使用鎖機(jī)制來確保同一時(shí)刻只有一個(gè)線程能夠修改共享內(nèi)存,在Java中一般是使用synchronized作為鎖機(jī)制,下面就讓我們來學(xué)習(xí)一下如何使用synchronized實(shí)現(xiàn)線程安全吧
    2023-08-08
  • 深入淺析Java中的volatile

    深入淺析Java中的volatile

    volatile是Java提供的一種輕量級(jí)的同步機(jī)制,在并發(fā)編程中,它也扮演著比較重要的角色.這篇文章主要介紹了深入淺析Java中的volatile,需要的朋友可以參考下
    2017-03-03
  • Java不要再使用!=null判空了!

    Java不要再使用!=null判空了!

    這篇文章主要給大家介紹了關(guān)于Java不要再使用!=null判空的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java的包裝類特性總結(jié)

    Java的包裝類特性總結(jié)

    這篇文章主要介紹Java的包裝類的一些特性,包裝類的作用,哪些類屬于包裝類等,文中有詳細(xì)的代碼示例,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-05-05
  • 解決線程并發(fā)redisson使用遇到的坑

    解決線程并發(fā)redisson使用遇到的坑

    這篇文章主要介紹了解決線程并發(fā)redisson使用遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Spring中ApplicationContext的拓展功能詳解

    Spring中ApplicationContext的拓展功能詳解

    這篇文章主要介紹了Spring中ApplicationContext的拓展功能詳解,相對(duì)于BeanFactory來說,ApplicationContext除了提供BeanFactory的所有功能外,還有一些其他的功能,主要包括國(guó)際化支持、資源訪問、事件傳遞,需要的朋友可以參考下
    2024-01-01
  • Java中的main方法調(diào)用非靜態(tài)方法處理

    Java中的main方法調(diào)用非靜態(tài)方法處理

    這篇文章主要介紹了Java中的main方法調(diào)用非靜態(tài)方法處理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • SpringBoot實(shí)戰(zhàn):Spring如何找到對(duì)應(yīng)轉(zhuǎn)換器優(yōu)雅使用枚舉參數(shù)

    SpringBoot實(shí)戰(zhàn):Spring如何找到對(duì)應(yīng)轉(zhuǎn)換器優(yōu)雅使用枚舉參數(shù)

    這篇文章主要介紹了SpringBoot實(shí)戰(zhàn)中Spring是如何找到對(duì)應(yīng)轉(zhuǎn)換器優(yōu)雅的使用枚舉參數(shù),文中附有詳細(xì)的實(shí)例代碼有需要的朋友可以參考下,希望可以有所幫助
    2021-08-08

最新評(píng)論

凌云县| 汝州市| 大城县| 永安市| 广南县| 德昌县| 梅州市| 漯河市| 繁昌县| 武强县| 手机| 大方县| 庆城县| 长海县| 宝坻区| 永康市| 承德市| 广安市| 当涂县| 呼图壁县| 台北市| 肇源县| 乳源| 彭州市| 新民市| 岗巴县| 大邑县| 汉寿县| 额敏县| 崇州市| 环江| 新泰市| 珲春市| 聂荣县| 黄平县| 泌阳县| SHOW| 云和县| 田阳县| 沾益县| 三河市|