最近在写一个配置中心的客户端,碰到一个问题,没有想到特别好的解决方案,和大家讨论下。
问题是这样的:
当配置发生变更时,我想自动更新 spring bean 中的 @Value 字段。 看了下有一些开源实现用的是基于反射的方式,通过设置 field 的值来实现更新
但是这样会有个问题,就是配置更新的线程修改了 field 的值,并不能保证用户其他线程可以看见最新的更改 (如果 field 上没有加 volatile,synchronized 这些保证可见性的关键字)。 但是不少开源实现好像都没有关注这个问题。
我能想到的方法:
- 让用户自己加 volatile 。这种最简单,但是需要让用户了解你的实现方式,算是比较侵入的方式,不透明。
- 通过 java agent 修改字节码,为符合条件的字段添加 volatile 。这种容易实现,但是增加接入成本,需要修改启动参数,就为了这个功能,感觉不大划算。
- 使用 annotation processor,通过和 lombok 类似的方式,直接在 pre compile 阶段修改源码。这种方式较难实现,并且比较 hack,毕竟 java 并不想让用户通过这种方式修改已存在的源码文件,它只是想让用户增加新的文件。
最后的问题:
- 为什么那些开源实现没有考虑并发可见性的情况?是我想错了吗?
- 有什么比较好的方式能够在不侵入代码的前提下,保证修改配置后的并发可见性?

