spring修改外部自定義配置文件且實時生效

前言

相信大家在開發(fā)中會有需要外部自定義配置文件塌西,且以外部自定義配置文件中的配置值優(yōu)先筹淫,同時要求對外部自定義配置文件中的配置修改后實時生效的需求饰剥。下面介紹如何實現(xiàn):

引入依賴

項目基于spring boot 2.2.6實現(xiàn)汰蓉,需要spring-cloud-context組件來完成動態(tài)刷新祝钢,具體版本與自己的項目匹配。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.6.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
  </parent>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-context</artifactId>
      <version>2.2.6.RELEASE</version>
    </dependency>

定義外部自定義配置文件路徑常量

package com.harrysharing.demo.constant;

/**
 * 系統(tǒng)級常量定義
 * 
 * @author harrysharing
 * @date 2020/05/08 10:54:01
 * @Copyright: ?2020 harrysharing 版權(quán)所有
 */
public class SystemConstant {
    /**
     * 自定義配置文件路徑霎冯,分別對應(yīng)生產(chǎn)慷荔、測試监徘、本地
     */
    public static final String[] FILE_LIST =
        {"/home/demo/myConfig.properties", "/home/demo_test/myConfig.properties", "d:/demo/myConfig.properties"};
}

啟動時加載外部自定義配置文件户敬,且以外部配置優(yōu)先忠怖,同時獲取配置文件最后修改時間

package com.harrysharing.demo.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.config.ConfigFileApplicationListener;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;

import com.harrysharing.demo.constant.SystemConstant;

/**
 * 加載自定義配置文件
 * 
 * @author harrysharing
 * @date 2020/12/15 16:26:09
 * @Copyright: ?2020 harrysharing 版權(quán)所有
 */
public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
    public static long FILE_LAST_MODIFIED = 0L;

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
//      if (application.getWebApplicationType().name().equals(WebApplicationType.NONE.name())) {
//          return;
//      }
        for (String conf : SystemConstant.FILE_LIST) {
            File f = new File(conf);
            if (f.exists()) {
                FILE_LAST_MODIFIED = f.lastModified();
                Properties p = new Properties();
                try {
                    p.load(new FileInputStream(f));
                    environment.getPropertySources().addFirst(new PropertiesPropertySource(f.getName(), p));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                break;
            }
        }
    }

    @Override
    public int getOrder() {
        return ConfigFileApplicationListener.DEFAULT_ORDER + 5;
    }

}

在src/main/resources目錄下增加META-INF目錄抄瑟,在其下添加spring.factories文件凡泣,指向剛才創(chuàng)建的自定義環(huán)境加載類。內(nèi)容如下:

org.springframework.boot.env.EnvironmentPostProcessor=com.harrysharing.demo.util.CustomEnvironmentPostProcessor

定時檢查配置文件是否修改皮假,若修改則進(jìn)行動態(tài)刷新

package com.harrysharing.demo.job;

import java.io.File;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.harrysharing.demo.constant.SystemConstant;
import com.harrysharing.demo.util.CustomEnvironmentPostProcessor;

/**
 * 定時檢查配置文件變更及動態(tài)刷新任務(wù)
 * 
 * @author harrysharing
 * @date 2020/12/15 16:27:07
 * @Copyright: ?2020 harrysharing 版權(quán)所有
 */
@Component
public class ConfigLoadTask {
    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigLoadTask.class);
    @Autowired
    private ContextRefresher contextRefresher;

    @Scheduled(initialDelay = 1000 * 60, fixedDelay = 1000 * 60)
    public void compareAndRefresh() {
        for (String conf : SystemConstant.FILE_LIST) {
            File f = new File(conf);
            if (f.exists()) {
                if (CustomEnvironmentPostProcessor.FILE_LAST_MODIFIED == f.lastModified()) {
                    return;
                }
                LOGGER.info("發(fā)現(xiàn)配置文件有變更鞋拟,執(zhí)行動態(tài)刷新。conf={}", conf);
                contextRefresher.refresh();
                break;
            }
        }
    }
}

實際應(yīng)用

在需要動態(tài)刷新配置的類上增加@RefreshScope注解惹资,在需要動態(tài)刷新的配置類變量上增加@Value注解贺纲,同時該類也必須由spring管理。

package com.harrysharing.demo.service;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import com.alibaba.druid.util.StringUtils;
import com.harrysharing.demo.entity.CodeEnum;
import com.harrysharing.demo.exception.BizException;
import com.harrysharing.demo.mapper.UserMasterMapper;
import com.harrysharing.demo.model.UserMaster;
import com.harrysharing.demo.util.Sha256;
import com.harrysharing.framework.db.util.DbUtil;
import com.harrysharing.framework.util.PageInfo;
import com.harrysharing.framework.util.SnowflakeShardingKeyGenerator;

/**
 * 用戶管理服務(wù)
 * 
 * @author harrysharing
 * @date 2020/08/05 18:29:26
 * @Copyright: ?2020 harrysharing 版權(quán)所有
 */
@RefreshScope
@Service
public class UserMasterService {
    @Autowired
    private UserMasterMapper userMasterMapper;
    @Autowired
    private SnowflakeShardingKeyGenerator shardingKeyGenerator;
    @Value("${maxPageSize}")
    private int maxPageSize;

    /**
     * 根據(jù)條件分頁查詢用戶列表
     * 
     * @param paraMap
     *            查詢條件
     * @return PageInfo 分頁對象
     * @author harrysharing
     * @date 2020/08/19 16:33:56
     */
    public PageInfo<UserMaster> queryPageList(Map<String, Object> paraMap) {
        if (paraMap == null || paraMap.isEmpty()) {
            throw new BizException(CodeEnum.INVALID_PARAM);
        }
        Object paraObj = paraMap.get("page");
        if (paraObj == null) {
            throw new BizException(CodeEnum.INVALID_PARAM);
        }

        if (!StringUtils.isNumber(paraObj.toString())) {
            throw new BizException(CodeEnum.INVALID_PARAM);
        }
        int page = Integer.parseInt(paraObj.toString());
        int userPageSize = maxPageSize;
        paraObj = paraMap.get("pageSize");
        if (paraObj != null) {
            if (!StringUtils.isNumber(paraObj.toString())) {
                throw new BizException(CodeEnum.INVALID_PARAM);
            }
            userPageSize = Integer.parseInt(paraObj.toString());
        }
        PageInfo<UserMaster> pi =
            DbUtil.queryPageList(userMasterMapper, paraMap, page, userPageSize, "create_time desc", maxPageSize);
        if (pi.getSize() == 0) {
            throw new BizException(CodeEnum.NO_RESULT);
        }
        return pi;
    }

   

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末褪测,一起剝皮案震驚了整個濱河市猴誊,隨后出現(xiàn)的幾起案子潦刃,更是在濱河造成了極大的恐慌,老刑警劉巖稠肘,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件福铅,死亡現(xiàn)場離奇詭異,居然都是意外死亡项阴,警方通過查閱死者的電腦和手機(jī)滑黔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來环揽,“玉大人略荡,你說我怎么就攤上這事∏附海” “怎么了汛兜?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長通今。 經(jīng)常有香客問我粥谬,道長,這世上最難降的妖魔是什么辫塌? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任漏策,我火速辦了婚禮,結(jié)果婚禮上臼氨,老公的妹妹穿的比我還像新娘掺喻。我一直安慰自己,他們只是感情好储矩,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布感耙。 她就那樣靜靜地躺著,像睡著了一般持隧。 火紅的嫁衣襯著肌膚如雪即硼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天屡拨,我揣著相機(jī)與錄音谦絮,去河邊找鬼。 笑死洁仗,一個胖子當(dāng)著我的面吹牛层皱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赠潦,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼叫胖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了她奥?” 一聲冷哼從身側(cè)響起瓮增,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤怎棱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绷跑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拳恋,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年砸捏,在試婚紗的時候發(fā)現(xiàn)自己被綠了谬运。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡垦藏,死狀恐怖梆暖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掂骏,我是刑警寧澤轰驳,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站弟灼,受9級特大地震影響级解,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜田绑,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一勤哗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辛馆,春花似錦俺陋、人聲如沸豁延。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诱咏。三九已至苔可,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間袋狞,已是汗流浹背焚辅。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留苟鸯,地道東北人同蜻。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像早处,于是被迫代替她去往敵國和親湾蔓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容