Bug 的起因

项目代码里, 利用了 Guava 缓存库作为本地缓存来使用, 但是构造时, 用了 Spring 注入的 properties . 示例代码如下:

private static final Cache<Integer, Boolean> checkFlagCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(moneyNoCheckSec, TimeUnit.SECONDS).build();

其中 moneyNoCheckSec@Value("${money.no.check.sec}") private int moneyNoCheckSec;

因为这个 cache 对象是 static final , 导致它已经初始化完了(但这时 moneyNoCheckSec 字段, Spring 容器还没有注入完毕, 所以, 导致这个字段为默认值 0).

如果这个参数值为0的话, 对 Gauva 来说就是失效的缓存了的. 所以在读取的时候, 就是一直为空了.

解决办法

知道了原因, 那就好办了. 因为这个缓存代码依赖于 Spring 的注入, 所以必须要等到 Spring 注入完毕后, 才能初始化这个代码, 可以将它放在 @PostConstruct 注解声明的方法里, 让 Spring 容器一切就绪之后, 才初始化这个缓存对象即可:

    @PostConstruct
    public void init() {
        checkFlagCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(moneyNoCheckSec, TimeUnit.SECONDS).build();
    }