【问题解决】jasypt-spring-boot-starter导致apollo动态配置刷新失效

背景

1.项目中关于数据库密码等信息想要进行加密处理,所以引入了jasypt-spring-boot-starter,版本3.0.3
2.后来项目接入了apollo的动态配置中心,apollo-client-config-data版本1.9.1
3.此时发现@Value的值,不能进行动态刷新,当发布新配置时,apollo会进行更新操作,可是程序里仍旧是旧值
4.通过查看文件,可以看到本地拉下来的配置文件中,值已经同步成和apollo配置中心一样。

原因

这块我理解的还不够透彻,大家可以看一下apollo的这个issues,等我研究明白了我再写,先看这个吧
apollo跟jasypt-spring-boot-2.1.0.jar不兼容

解决方案

方案一

高版本jasypt会有这个问题,其他博客说1.18/1.16版本可以用,应该是2.0.0以下的都可以,我尝试没成功,大家也可以参考一下。

方案二

照着issues里的方案整了一版,但是不太稳定,还没搞明白为啥,但是能用,直接上代码:

@Order(-12312931)
public class ApolloConfigChangeListener implements ConfigChangeListener {
    public ApolloConfigChangeListener() {
    }

    @Override
    public void onChange(ConfigChangeEvent changeEvent) {
        changeEvent.changedKeys().forEach(k -> {
            this.refresh();
        });
    }

    public void refresh() {
        refreshCachedProperties();
    }

    private void refreshCachedProperties() {
        ConfigurableApplicationContext context = (ConfigurableApplicationContext) SpringContextUtil.getApplicationContext();

        PropertySources propertySources = context.getEnvironment().getPropertySources();
        propertySources.forEach(this::refreshPropertySource);
    }

    @SuppressWarnings("rawtypes")
    private void refreshPropertySource(PropertySource<?> propertySource) {
        if (propertySource instanceof CompositePropertySource) {
            CompositePropertySource cps = (CompositePropertySource) propertySource;
            cps.getPropertySources().forEach(this::refreshPropertySource);
        } else if (propertySource instanceof EncryptablePropertySource) {
            EncryptablePropertySource eps = (EncryptablePropertySource) propertySource;
            eps.refresh();
        }
    }
}

为此还写了个工具类:

public class SpringContextUtil {
    private static ApplicationContext applicationContext;
    //获取上下文
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    //设置上下文
    public static void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextUtil.applicationContext = applicationContext;
    }
    //通过名字获取上下文中的bean
    public static Object getBean(String name){
        return applicationContext.getBean(name);
    }
    //通过类型获取上下文中的bean
    public static Object getBean(Class<?> requiredType){
        return applicationContext.getBean(requiredType);
    }
}

然后启动类也要做修改,修改main方法:

    public static void main(String[] args) {
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
        ApplicationContext context = SpringApplication.run(BmsWebApplication.class, args);
        SpringContextUtil.setApplicationContext(context);
        //这里application.yml是我要关注的apollo里面的那个配置文件
        ConfigService.getConfig("application.yml")
                .addChangeListener(new ApolloConfigChangeListener());
    }

总结

经过以上修改,配置是能实时更新的,可是不太稳定,偶尔会出现值没更新的情况,此时多改几次就可以了,我还没搞清楚为什么,希望有比较懂的大神评论告诉我,感谢

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盖丽男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值