我有以下类和接口(为简化起见而简化)。
@Serivce
class Service1 {
@Cacheable("cacheName")
public Metadata preLoadMetadata() {
// load data from database
}
}
@Service
class Service2 implements Loader {
@Autowired @Lazy
private Service1 service1;
@Overrride
public CacheWrapper getCacheWrapper() {
return new CacheWrapper(() -> service1.preLoadMetadata());
}
}
interface Loader {
CacheWrapper getCacheWrapper();
}
class CacheWrapper {
private Callable callable;
public CacheWrapper(Callable callable) {
this.callable = callable;
}
public getCallable() {
return callable;
}
}
Spring bean负责在部署时加载缓存。
@Component
class LoadCache {
@Autowired
private List<Loader> allLoaders;
@PostConstruct
public void load() {
allLoaders.getCacheWrapper().getCallable().call();
}
}
preLoadMetadata()
不会将数据保存在缓存中,但会执行。部署完成后,我再次调用相同的方法preLoadMetadata()
,然后将数据保存在缓存中。
为什么@Cacheable
在部署时无效?
如果我手动使用put
Cache
方法在@PostConstruct
注释的方法中填充缓存,我可以在部署时成功完成。
我使用Tomcat作为服务器 我在Spring缓存抽象后面使用Couchbase缓存。
答案 0 :(得分:1)
如果您想预加载缓存,我建议您使用一个ApplicationListener
,它将在您的应用程序启动后执行:
@Component
public class CacheInitializer implements ApplicationListener<ContextRefreshedEvent>{
@Autowired
private List<Loader> allLoaders;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
allLoaders.getCacheWrapper().getCallable().call();
}
}
答案 1 :(得分:0)
Cacheable
注释不起作用的根本原因:
仅当afterSingletonsInstantiated()
已实例化所有bean时,initialized
方法才将BeanFactory
标志设置为true。如果initialized
标志为false,则不执行缓存操作。这里,在post构造内部,当我们开始预加载缓存时,LoadCache
很可能不是要实例化的最后一个bean。因此,不执行缓存操作(使用缓存注释时)。
因此,响应EventListener
的{{1}}注释是在这种情况下使用的最佳选择,它确保上下文已经开始,然后只加载缓存。