美文网首页IT技术篇
spring修改外部自定义配置文件且实时生效

spring修改外部自定义配置文件且实时生效

作者: 哈利爱分享 | 来源:发表于2020-12-23 17:51 被阅读0次

前言

相信大家在开发中会有需要外部自定义配置文件,且以外部自定义配置文件中的配置值优先,同时要求对外部自定义配置文件中的配置修改后实时生效的需求。下面介绍如何实现:

引入依赖

项目基于spring boot 2.2.6实现,需要spring-cloud-context组件来完成动态刷新,具体版本与自己的项目匹配。

<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;

/**
 * 系统级常量定义
 * 
 * @author harrysharing
 * @date 2020/05/08 10:54:01
 * @Copyright: ©2020 harrysharing 版权所有
 */
public class SystemConstant {
    /**
     * 自定义配置文件路径,分别对应生产、测试、本地
     */
    public static final String[] FILE_LIST =
        {"/home/demo/myConfig.properties", "/home/demo_test/myConfig.properties", "d:/demo/myConfig.properties"};
}

启动时加载外部自定义配置文件,且以外部配置优先,同时获取配置文件最后修改时间

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 版权所有
 */
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文件,指向刚才创建的自定义环境加载类。内容如下:

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

定时检查配置文件是否修改,若修改则进行动态刷新

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;

/**
 * 定时检查配置文件变更及动态刷新任务
 * 
 * @author harrysharing
 * @date 2020/12/15 16:27:07
 * @Copyright: ©2020 harrysharing 版权所有
 */
@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("发现配置文件有变更,执行动态刷新。conf={}", conf);
                contextRefresher.refresh();
                break;
            }
        }
    }
}

实际应用

在需要动态刷新配置的类上增加@RefreshScope注解,在需要动态刷新的配置类变量上增加@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;

/**
 * 用户管理服务
 * 
 * @author harrysharing
 * @date 2020/08/05 18:29:26
 * @Copyright: ©2020 harrysharing 版权所有
 */
@RefreshScope
@Service
public class UserMasterService {
    @Autowired
    private UserMasterMapper userMasterMapper;
    @Autowired
    private SnowflakeShardingKeyGenerator shardingKeyGenerator;
    @Value("${maxPageSize}")
    private int maxPageSize;

    /**
     * 根据条件分页查询用户列表
     * 
     * @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;
    }

   

}

相关文章

网友评论

    本文标题:spring修改外部自定义配置文件且实时生效

    本文链接:https://www.haomeiwen.com/subject/nekunktx.html