使用命令行参数初始化静态缓存

时间:2017-06-20 05:51:15

标签: java caching static

我有一个使用静态缓存的类,该缓存在类的所有实例之间共享。我希望能够在运行时设置缓存的超时。

提供具体的用例:我缓存从云存储中获取的值。我想在开发环境中比在prod中更快地刷新值。部署代码时,它会获取与该环境对应的配置文件的参数。此配置文件可以包含缓存刷新时间的值。

public class Pipeline {
    private static final LoadingCache<BlobId, Definitions> CACHE =
        CacheBuilder.newBuilder()
                    .refreshAfterWrite(VALUE, TimeUnit.MINUTES) // <-- how do I set VALUE from a config file?
                    .build(
               new CacheLoader<BlobId, Definitions>() {
                   public Definitions load(BlobId key) throws Exception {
                       return DefinitionsLoader.load(key);
                   }
               });
...
}

2 个答案:

答案 0 :(得分:0)

要在运行时动态加载不同的配置,您可以使用 .properties 文件。在下面的示例中,我将属性文件加载到静态块中,但您也可以在初始化缓存的静态方法中实现逻辑。

https://docs.oracle.com/javase/tutorial/essential/environment/properties.html

private static final LoadingCache<BlobId, Definitions> CACHE;
static {
    Properties prop = new Properties();
    try {
        prop.load(new FileInputStream("config.properties"));
    } catch (IOException e) {
        // handle exception
    }

    Long value = Long.parseLong(prop.getProperty("value", "5")); 
    CACHE = CacheBuilder.newBuilder()
            .refreshAfterWrite(value, TimeUnit.MINUTES)
            .build(new CacheLoader<Integer, Definitions>() {
                public Definitions load(BlobId key) throws Exception {
                    return DefinitionsLoader.load(key);
                }
            });

}

答案 1 :(得分:0)

在声明中初始化的静态字段不是为了进行参数化而设计的。

此外,您的缓存加载不灵活 如果明天你改变主意或想要使用其中的多个,你就不能。
最后,它也是不可测试的。

如果要为缓存加载提供特定行为,最自然的方法是更改​​包含该字段的类的API。

您可以为Pipeline构造函数提供long delayInMnToRefresh参数,您可以使用此参数来设置缓存的刷新时间。

public Pipeline(int delayInMnToRefresh){
        CacheBuilder.newBuilder()
                    .refreshAfterWrite(delayInMnToRefresh, TimeUnit.MINUTES)
       ....
}

如果你使用Spring,你可以使用@Autowired构造函数,它在加载Spring上下文时使用在运行时定义的属性:

@Autowired
public Pipeline(@Value("${clould.cache.delayInMnToRefresh}") int delayInMnToRefresh){

       ....
}

使用以这种方式定义的属性,例如在env:

  

clould.cache.delayInMnToRefresh = 5

以这种方式定义的另一个属性,例如prod:

  

clould.cache.delayInMnToRefresh = 15

当然,您可以在没有Spring(和Spring Boot)的情况下实现此要求,但您应该执行更多的样板任务(在调用此方法之前加载属性文件并自己处理环境概念)。