springboot - 实现动态刷新配置

这篇具有很好参考价值的文章主要介绍了springboot - 实现动态刷新配置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

自定义的配置数据源,继承自Spring框架的 MapPropertySource 类,从一个名为 my.properties 的文件中读取配置信息,并在每10秒钟刷新一次。

这里不加@Component,是因为:
FilePropertiesSource filePropertiesSource = new FilePropertiesSource();
// 属性源是按照添加的顺序进行合并的,后添加的属性源中的属性会覆盖前面添加的属性源中的同名属性。
// 因此,为了确保我们自定义的属性源中的属性优先级最高,我们需要将它添加到属性源列表的最后。这样就能保证后添加的属性源中的属性值会覆盖之前的同名属性。
environment.getPropertySources().addLast(filePropertiesSource);


import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.MapPropertySource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * 自定义的配置数据源,继承自Spring框架的 MapPropertySource 类,从一个名为 my.properties 的文件中读取配置信息,并在每10秒钟刷新一次。
 * @author Administrator
 */
@Slf4j
//@Component
public class FilePropertiesSource extends MapPropertySource {

    private static final Logger logger = LoggerFactory.getLogger(FilePropertiesSource.class);


    private static final String CONFIG_FILE_NAME = "my.properties";
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public FilePropertiesSource() {
        super("filePropertiesSource", new HashMap<>());
    }

    /**
     * 从配置文件中读取配置,10s 更新一次
     */
    @PostConstruct
    @Scheduled(fixedRate = 10_000)
    public void refreshSource() throws IOException {
        logger.info("开始读取配置文件 {}", CONFIG_FILE_NAME);
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(CONFIG_FILE_NAME);
        if (inputStream == null) {
            throw new FileNotFoundException("配置文件 " + CONFIG_FILE_NAME + " 不存在");
        }

        Map<String, String> newProperties = new HashMap<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                if (StringUtils.isEmpty(line) || line.startsWith("#")) {
                    continue;
                }
                String[] pair = StringUtils.split(line, "=");
                if (pair == null || pair.length != 2) {
                    logger.warn("忽略配置项 {}", line);
                    continue;
                }
                String key = pair[0].trim();
                String value = pair[1].trim();
                logger.debug("读取配置项 {} = {}", key, value);
                newProperties.put(key, value);
            }
        } catch (IOException e) {
            logger.error("读取配置文件 {} 出现异常:{}", CONFIG_FILE_NAME, e.getMessage(), e);
            throw e;
        }

        synchronized (this) {
            source.clear();
            source.putAll(newProperties);
        }

        logger.info("读取配置文件完成,共读取 {} 个配置项,时间 {}", newProperties.size(), LocalDateTime.now().format(DATE_TIME_FORMATTER));
    }


    /**
     * 覆盖 getProperty 方法,实现实时获取配置
     *
     * @param key 配置项的 key
     * @return 配置项的值
     */
    @Override
    public Object getProperty(String key) {
        return source.get(key);
    }
}

定义一个Spring配置类,定义了一个名为 filePropertiesSource 的Bean,并将其加入到环境变量中。


import com.lfsun.bootdynamicenv.config.FilePropertiesSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;


/**
 * 一个Spring配置类,定义了一个名为 filePropertiesSource 的Bean,并将其加入到环境变量中。
 */
@Configuration
public class AutoConfig {
    @Bean
    public FilePropertiesSource filePropertiesSource(ConfigurableEnvironment environment) {
        FilePropertiesSource filePropertiesSource = new FilePropertiesSource();
        // 属性源是按照添加的顺序进行合并的,后添加的属性源中的属性会覆盖前面添加的属性源中的同名属性。
        // 因此,为了确保我们自定义的属性源中的属性优先级最高,我们需要将它添加到属性源列表的最后。这样就能保证后添加的属性源中的属性值会覆盖之前的同名属性。
        environment.getPropertySources().addLast(filePropertiesSource);
        return filePropertiesSource;
    }
}

为了方便直接用启动类作为控制层

@DependsOn(“filePropertiesSource”) 依赖于filePropertiesSource,以实现刷新配置。
@EnableScheduling 实现定时刷新
private String userName; 会被计算机名称覆盖,计算机名称优先级最高

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@DependsOn("filePropertiesSource")
@EnableScheduling
@RestController
@SpringBootApplication
public class Application {
    @Autowired
    private Environment environment;

    @Value("${user-name}")
    private String userName;


    @GetMapping(path = "get")
    public String getProperty(String key) {
        return userName + "  |  " + environment.getProperty(key);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

实现效果

springboot - 实现动态刷新配置
访问:http://localhost:8080/get?key=my-user-id
springboot - 实现动态刷新配置
可见修改user-name无效,被计算机名称所覆盖。
这时候修改my-user-id=
springboot - 实现动态刷新配置
再访问:http://localhost:8080/get?key=my-user-id
springboot - 实现动态刷新配置
已实现刷新:

ext:

@PostConstruct:

用于指定在依赖注入完成后需要执行的初始化方法。具体来说,当Spring容器完成对一个bean的依赖注入后,会调用该bean中使用了@PostConstruct注解的方法。

例如,如果在一个类中定义了一个方法,并在该方法上添加了@PostConstruct注解,那么当Spring容器初始化该类时,会自动调用该方法,以完成一些必要的初始化操作。

@PostConstruct注解的方法不能带有任何参数,也不能有返回值,因为Spring不会使用这些返回值。如果需要返回一些状态信息,可以使用类成员变量来保存这些信息。另外需要注意的是,@PostConstruct注解只能用于非静态方法。

@Scheduled(fixedRate = 10_000)

@Scheduled是一个Spring框架提供的注解,用于实现基于时间的任务调度。通过在方法上添加@Scheduled注解,并指定相应的属性,可以使得该方法在指定的时间间隔内自动执行。

例如,@Scheduled(fixedRate = 10_000)表示每隔10秒执行一次该方法。fixedRate属性指定了执行方法的时间间隔,单位为毫秒。除此之外,还可以使用cron表达式指定执行时间,如@Scheduled(cron = “0 0 12 * * ?”)表示每天中午12点执行一次该方法。

需要注意的是,使用@Scheduled注解的方法必须是无参方法,且返回类型为void或Future。如果需要传递参数或返回结果,可以使用实例变量或方法返回值进行传递。同时,为了使得@Scheduled注解生效,需要在启动类上面@EnableScheduling文章来源地址https://www.toymoban.com/news/detail-430042.html

到了这里,关于springboot - 实现动态刷新配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot项目整合OpenFeign、实现动态IP+URL请求、自定义(编码器\解码器)

    OpenFeign 是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中. 启动类加上注解: @EnableDiscoveryClient 动态URL 工具类: FeignUtils.class

    2024年02月02日
    浏览(39)
  • springboot-rabbitmq 实现动态配置监听容器

    1.1.1从factories我们可以看到mq的启动配置类 1.1.2然后我们找到 RabbitAutoConfiguration ,发现它引入了 RabbitAnnotationDrivenConfiguration 这个配置类 1.1.3进入 RabbitAnnotationDrivenConfiguration 滑到最低部看到这里引入了 @EnableRabbit 这个注解,找个注解里面又引出 RabbitBootstrapConfiguration 这个配置类

    2023年04月09日
    浏览(63)
  • nacos配置动态刷新及监听到变化触发一些方法

    在使用spring 时,动态更新配置是常见的,属性值更新,但是需要开启支持刷新功能,一个是spring.cloud.nacos.config.isRefreshEnabled=true; 这个值一般是默认的,可以在nacosConfigProperties这个类中看到。还要在扩展配置中开启refresh = true 测试结果: 配置中心值改变,对应的属性值也改变

    2024年02月04日
    浏览(33)
  • SpringBoot【集成 jasypt】实现配置信息自定义加解密(自定义的属性探测和密码解析器)

    Jasypt是一个Java简易加密库,用于加密配置文件中的敏感信息,如数据库密码。它可以帮助开发人员在应用程序中加密密码、敏感信息和数据通信,还包括高安全性、基于标准的加密技术、可同时单向和双向加密的加密密码、文本、数字和二进制文件。如果您正在使用Spring B

    2024年02月05日
    浏览(33)
  • springboot git配置文件自动刷新失败问题排查

    ​​​​​​​http://{ip}:{port}/refresh 刷新配置接口如上  说明:当前项目springBoot版本是1.5.9,接口路径与2.x不同 路径区别:/refresh  VS / actuator/refresh 用postman调用refresh接口刷新git配置,报错如下,没有权限 在服务本地启动,调用refresh接口,日志如下: 2024-01-08 15:18:25.663 [IN

    2024年01月22日
    浏览(28)
  • Springboot 实践(18)Nacos配置中心参数自动刷新测试

            前文讲解了Nacos 2.2.3配置中心的服务端的下载安装,和springboot整合nacos的客户端。Springboot整合nacos关键在于使用的jar版本要匹配,文中使用版本如下:         ☆ springboot版本:   2.1.5.RELEASE         ☆ spring cloud版本  Greenwich.RELEASE         ☆ spring clou

    2024年02月07日
    浏览(30)
  • Echarts实现动态折线图的定时刷新

    在做项目的过程中,遇到一个需求:要从后台读取数据,并对echarts进行实时更新。先来看下实现的效果图: 首先来看一下没有和后台交互的echarts动态折线图如何实现,代码如下: 前面实现的是动态折现图并没有和后台交互,接下来看一下和后台交互的代码是如何实现的:

    2024年02月12日
    浏览(30)
  • Springboot 实践(14)spring config 配置与运用--手动刷新

            前文讲解Spring Cloud + zuul 实现了 SpringbootAction-One 和SpringbootAction-two两个项目的路由切换,正确访问到项目中的资源。这两个项目各自拥有一份application.yml项目配置文件,配置文件中有一部分相同的配置参数,如果涉及到修改,需要进行多处修改。那么有没有一种技

    2024年02月09日
    浏览(34)
  • vue3实现动态菜单和动态路由和刷新后白屏处理

    项目中,当每一个角色得到的界面不一致的时候,我们就不能使用静态菜单了,而是要从后端得到动态的菜单数据,然后动态的将菜单数据展示在界面上。 除了在界面展示,也还要将界面的路由动态添加,在路由动态添加之后,你可能会出现刷新界面,界面变白的情况,页面

    2024年02月06日
    浏览(37)
  • springboot dynamic-datasource 实现动态切换数据源-多租户-配置文件切换-基于dynamic-datasource

    1、实现动态切换数据源 2、实现配置多数据源 3、实现读写分离也可以用多数据源方式 4、选择 dynamic-datasource集成了很多ORM的框架,其中,使用比较多的是druid,但有一些东西开始收费了 druid也可以自行配置,配置多了点 目前版本只支持单一位置加载数据源(只能从配置文件或

    2024年02月09日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包