基于Mysql实现Spring配置动态刷新

Spring为我们提供了@Value和Environment来获取配置信息,但是很遗憾,不支持动态刷新配置,也就是说在配置更新之后,需要重启项目才能获取到最新的配置信息,如果要实现动态刷新,通常我们需要借助第三方配置中心,比如百度的disconf,携程的apollo、阿里的nacos等等,但这些都需要额外维护一套配置中心,下面介绍一种简单的思路来实现Environment获取最新配置的方式,基于这个思路再去实现@Value动态刷新就简单多了,本文暂不介绍@Value的方式,废话不多说,直接上代码:

1、准备数据:

CREATE TABLE `t_config` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `key` varchar(255) DEFAULT NULL,
  `value` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
insert INTO t_config(`key`,`VALUE`) VALUES('test.tj','www.baidu.com');

2、Java代码实现:

  1. 生成一个springboot项目,这个在spring官网可以一键生成,不做赘述
  2. 在springboot项目的启动类上实现两个接口:
    EnvironmentAware, CommandLineRunner,至于这两个接口到底有什么用,自行百度,这里就不做介绍了
  3. 重写setEnvironment和run方法(这个方法不是多线程的那个run方法,是CommandLineRunner这个接口的方法):
  4. setEnvironment实现:
    @Override
    public void setEnvironment(Environment environment) {
        this.configurableEnvironment = (ConfigurableEnvironment) environment;
    }
  5. run实现:
    @Override
    public void run(String... args) throws Exception {
        Config config = new Config();
        String url = "jdbc:mysql://127.0.0.1:3306/config?serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false";
        String username = "root";
        String password = "123456";
        Connection connection = DriverManager.getConnection(url, username, password);
        String sql = "select `key`,`value` from t_config";
        new Thread(() -> {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    PreparedStatement preparedStatement = connection.prepareStatement(sql);
                    ResultSet resultSet = preparedStatement.executeQuery();
                    while (resultSet.next()) {
                        String key = resultSet.getString("key");
                        String value = resultSet.getString("value");
                        config.addKey(key, value);
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                configurableEnvironment.getPropertySources().addFirst(new MyPropertySource("myPropertySource", config));
            }
        }).start();
    }
  6. 其中用到的几个自定义的类:
    public class MyPropertySource extends EnumerablePropertySource<Config> {
        private static final String[] EMPTY_ARRAY = new String[0];
    
        public MyPropertySource(String name, Config config) {
            super(name, config);
        }
    
        @Override
        public String[] getPropertyNames() {
            Set<String> propertyNames = this.source.getPropertyNames();
            if (propertyNames.isEmpty()) {
                return EMPTY_ARRAY;
            }
            return propertyNames.toArray(new String[propertyNames.size()]);
        }
    
        @Override
        public Object getProperty(String name) {
            return this.source.getProperty(name, null);
        }
    }
    
    public class Config {
    
        private Map<String, Object> cache = new HashMap<>();
    
        public Object getProperty(String key, String defaultValue) {
            Object o = cache.get(key);
            return o;
        }
    
        public Set<String> getPropertyNames() {
            return cache.keySet();
        }
    
        public void addKey(String key, Object value) {
            cache.put(key, value);
        }
    }
  7. 测试:127.0.0.1:8081/test/getCfg
    @Controller
    public class TestController {
    
        @Value("${test.tj}")
        private String myConfig;
    
        @Autowired
        private ConfigurableEnvironment configurableEnvironment;
    
        @RequestMapping("/test/index")
        @ResponseBody
        public String index() {
            return "index";
        }
    
        @RequestMapping("/test/getCfg")
        @ResponseBody
        public String getCfg() {
            return configurableEnvironment.getProperty("test.tj");
        }
    }
  8. 更改mysql数据库里面test.tj对应的value字段值,刷新浏览器就可以看到效果了
  9. @Value实现动态刷新的思路:通过spring容器获取所有的bean,然后对bean里面的属性进行遍历,看看有没有@Value注解,有的话就可以解析@Value里面的key值与数据库查出来的key对比,相等的话,通过反射将查出来的值set到对应的bean即可
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用中提供的信息,可以得知MySQL的版本是8.0.17。而关于Spring配置,可以在application.yml文件中找到相关信息。在该文件中,设置了数据源的驱动类名为com.mysql.cj.jdbc.Driver,并指定了连接URL、用户名和密码。因此,可以得出MySQL的版本是8.0.17,而Spring配置如下: spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/csvswitch?serverTimezone=GMT+8&characterEncoding=utf8&useSSL=true username: root password: password 请注意,这只是一个示例配置,实际应用中可能会有所不同。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Spring Boot 配置 MySQL 数据库](https://blog.csdn.net/qq_32046111/article/details/124946993)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Spring配置mysql数据库](https://blog.csdn.net/weixin_42591413/article/details/115905063)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值