成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

顛覆傳統(tǒng)!SpringBoot 配置文件熱加載實戰(zhàn),省下 50% 重啟時間

開發(fā) 前端
在實際項目迭代中,頻繁調(diào)整配置是常態(tài),而頻繁重啟服務則是浪費。通過本方案,我們可以大幅提升配置變更效率,節(jié)省無謂等待時間,提高服務的穩(wěn)定性與響應速度。

在構(gòu)建和運維基于 Spring Boot 的應用過程中,配置文件(如 application.yml 或 application.properties)充當著不可替代的角色。它們承載了項目的環(huán)境、服務參數(shù)、版本標識等關(guān)鍵信息。然而,傳統(tǒng)配置管理方式下,任何一次配置修改都需重啟服務,這在多環(huán)境部署和頻繁調(diào)試場景中尤顯低效。

為了從根本上改善這一痛點,本文將系統(tǒng)介紹如何基于 Spring Boot 3.4.5 + Spring Cloud Context 實現(xiàn)無需重啟即可動態(tài)更新配置文件的機制,覆蓋原理解析、實戰(zhàn)代碼、注意事項,助你提升至少 50% 的配置變更效率。

技術(shù)方案概覽

我們選用 Spring Cloud 提供的 ContextRefresher 作為核心實現(xiàn),結(jié)合 Apache Commons IO 實現(xiàn)本地配置文件變更監(jiān)聽,構(gòu)建完整的熱加載能力:

  • 監(jiān)聽配置文件變化;
  • 檢測到變化后刷新 Spring 容器中的 Bean;
  • 生效的配置必須綁定為 @ConfigurationProperties 且標注 @RefreshScope。

引入依賴(pom.xml)

在 pom.xml 中添加如下依賴:

<!-- 文件變更監(jiān)聽 -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>


<!-- 動態(tài)配置刷新 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-context</artifactId>
    <version>4.1.0</version>
</dependency>

編寫基礎(chǔ)配置文件

路徑:src/main/resources/application.yml

app:
  name: auto-config-demo
  version: 1.0.0
  description: 示例應用 - 支持配置動態(tài)更新

編寫配置綁定類

文件路徑:/src/main/java/com/icoderoad/config/ProjectConfig.java

package com.icoderoad.config;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;


@Component
@RefreshScope
@ConfigurationProperties(prefix = "app")
public class ProjectConfig {
    private String name;
    private String version;
    private String description;


    // Getter & Setter
}

說明:

  • @RefreshScope 是核心,保證配置類可在刷新時重新加載;
  • 使用 @ConfigurationProperties 綁定配置前綴。

編寫文件監(jiān)聽器

文件路徑:/src/main/java/com/icoderoad/listener/ConfigFileChangeListener.java

package com.icoderoad.listener;


import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.monitor.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;


import java.io.File;
import java.net.URL;
import java.nio.file.*;


@Slf4j
@Component
public class ConfigFileChangeListener {


    @Autowired
    private ApplicationContext context;


    @Autowired
    private ContextRefresher refresher;


    @PostConstruct
    public void init() throws Exception {
        String configPath = resolveConfigPath();
        if (configPath == null) return;


        File configFile = new File(configPath);
        FileAlterationObserver observer = new FileAlterationObserver(configFile.getParentFile());
        observer.addListener(new FileAlterationListenerAdaptor() {
            @Override
            public void onFileChange(File file) {
                if (file.getName().equals(configFile.getName())) {
                    log.info("配置文件變更:{}", file.getAbsolutePath());
                    refresher.refresh();
                    log.info("刷新成功!");
                }
            }
        });


        FileAlterationMonitor monitor = new FileAlterationMonitor(1000, observer);
        monitor.start();
        log.info("配置監(jiān)聽器啟動成功,監(jiān)聽路徑:{}", configPath);
    }


    private String resolveConfigPath() throws Exception {
        Environment env = context.getEnvironment();
        String configLocation = env.getProperty("spring.config.location");
        if (configLocation != null && !configLocation.isEmpty()) {
            return configLocation;
        }


        String defaultPath = "classpath:application.yml";
        if (context.getResource(defaultPath).exists()) {
            if (isRunningInJar()) {
                Path externalConfig = exportToExternal(defaultPath);
                return externalConfig.toString();
            } else {
                return context.getResource(defaultPath).getFile().getAbsolutePath();
            }
        }


        log.warn("未找到有效配置文件路徑");
        return null;
    }


    private boolean isRunningInJar() {
        try {
            URL location = getClass().getProtectionDomain().getCodeSource().getLocation();
            return location.getPath().endsWith(".jar");
        } catch (Exception e) {
            return false;
        }
    }


    private Path exportToExternal(String classpath) throws Exception {
        Path configDir = Paths.get(System.getProperty("user.dir"), "config");
        Files.createDirectories(configDir);


        String filename = classpath.substring("classpath:".length());
        Path configFile = configDir.resolve(filename);
        if (!Files.exists(configFile)) {
            try (var in = context.getResource(classpath).getInputStream()) {
                Files.copy(in, configFile);
            }
        }


        return configFile;
    }
}

提供測試接口

文件路徑:/src/main/java/com/icoderoad/controller/ConfigController.java

package com.icoderoad.controller;


import com.icoderoad.config.ProjectConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@RestController
@RequestMapping("/config")
public class ConfigController {


    @Autowired
    private ProjectConfig config;


    @GetMapping("/info")
    public ProjectConfig getInfo() {
        return config;
    }
}

調(diào)用 /config/info 接口可實時查看當前配置是否變更成功。

注意事項

  • 配置類必須使用 @ConfigurationProperties 和 @RefreshScope
  • 數(shù)據(jù)源配置、端口、Redis連接等啟動相關(guān)配置變更后不支持熱刷新;
  • 推薦將配置文件外置(配合 --spring.config.location)提高運維靈活性;
  • 熱加載僅對非結(jié)構(gòu)性配置(如描述、開關(guān)、調(diào)試參數(shù))更有意義。

寫在最后

在實際項目迭代中,頻繁調(diào)整配置是常態(tài),而頻繁重啟服務則是浪費。通過本方案,我們可以大幅提升配置變更效率,節(jié)省無謂等待時間,提高服務的穩(wěn)定性與響應速度。Spring Boot 配合 Spring Cloud Context + Commons IO,即可輕松實現(xiàn)配置熱加載,優(yōu)雅應對變更。

代碼路徑統(tǒng)一為 /src/main/java/com/icoderoad/... 配置文件推薦放置于 /config 目錄,并通過 --spring.config.location 顯式聲明。

責任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2021-04-22 07:43:24

后端技術(shù)SpringBootdevtools

2009-09-25 10:49:25

Hibernate加載

2022-03-23 07:31:34

SpringBoot加載配置

2022-04-20 20:27:51

Hydra配置文件開發(fā)工具

2021-04-01 10:23:45

SpringBootbootstrapapplication

2014-03-12 10:31:32

大數(shù)據(jù)

2025-06-23 08:23:04

2021-08-02 18:23:01

Spring隱私數(shù)據(jù)

2010-02-02 18:19:52

Linux mplay

2024-04-23 14:13:38

開發(fā)配置文件

2017-04-18 11:33:03

人工智能云計算醫(yī)療

2018-09-10 11:00:21

區(qū)塊鏈互聯(lián)網(wǎng)新聞行業(yè)

2013-08-06 17:38:20

2015-05-11 11:06:43

統(tǒng)一基礎(chǔ)架構(gòu)系統(tǒng)華三通信UIS

2017-12-20 11:55:38

RAID2.0傳統(tǒng)方式

2011-01-19 14:00:21

2011-01-13 16:27:26

Linux配置文件

2010-02-05 13:27:48

Ubuntu apac

2010-12-28 16:35:32

Outlook 配置文

2022-08-17 07:06:14

SpringBoot配置@Value
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日日草天天干 | 97caoporn国产免费人人 | 日韩视频二区 | 99re6在线视频精品免费 | 男女国产视频 | 国产精品99久久久精品免费观看 | 欧美成人激情视频 | 久久久这里只有17精品 | 国产精品国产精品国产专区不片 | 精品国产高清一区二区三区 | 成人在线免费观看视频 | 国产成人精品久久二区二区91 | 亚洲高清在线 | 欧美日韩三区 | 黄色毛片在线看 | 国产日韩欧美一区二区 | 51ⅴ精品国产91久久久久久 | 精品小视频 | 五月婷婷丁香婷婷 | 久久手机在线视频 | 亚州午夜精品 | 91av在线免费看 | 欧美性乱 | 国产在线精品一区 | 午夜丁香视频在线观看 | 亚洲精品一区二 | 午夜视频一区二区 | 岛国在线免费观看 | 福利视频一区二区 | 久久99精品久久久久久国产越南 | 久久精品一级 | 欧美黄色精品 | 久久久久久久久国产成人免费 | 成年人在线观看 | 欧美日韩在线一区二区三区 | 成人欧美一区二区三区黑人孕妇 | 黄色一级大片在线免费看产 | 欧美视频二区 | 亚洲人成人一区二区在线观看 | 欧美一区二区三区四区五区无卡码 | 欧美11一13sex性hd |