该应用程序使用spring,akka和mongodb。 它使用spring缓存来存储在mongo中的某些设置。该键由设置对象中的4个元素组成。缓存值应在创建后的X秒钟内更新或收回。
这是缓存服务:
@Component
public class SettingsCacheService {
@Cacheable(value = SETTINGS_CACHE_STORE, key = "{#k1, #k2, #k3, #k4}", sync = true)
public Settings readSettings(ActorSystem actorSystem, String k1, String k2, String k3, String k4) {
Settings settings = mongoUtils.getSettings(k1, k2, k3, k4);
ActorRef actor = SettingsCacheEvictScheduler.getActor(actorSystem, this, k1, k2, k3, k4);
actorSystem.scheduler().scheduleOnce(Duration.create(10000, TimeUnit.MILLISECONDS), new Runnable() {
@Override
public void run() {
actor.tell(SettingsCacheEvictScheduler.MESSAGE, ActorRef.noSender());
}
}, actorSystem.dispatcher());
return settings;
}
@CacheEvict(value = SETTINGS_CACHE_STORE, key = "{#k1, #k2, #k3, #k4}", beforeInvocation = true)
public void cacheEvict(SettingsCacheEvictScheduler settingsCacheEvictScheduler, String k1,
String k2, String k3, String k4) {
settingsCacheEvictScheduler.getSelf().tell(PoisonPill.getInstance(), ActorRef.noSender());
}
}
还有我创建的akka调度程序,用于从缓存中逐出值:
public class SettingsCacheEvictScheduler extends UntypedAbstractActor {
public final static String MESSAGE = "cacheEvict";
private SettingsCacheService settingsCacheService;
private String k1;
private String k2;
private String k3;
private String k4;
public SettingsCacheEvictScheduler(SettingsCacheService settingsCacheService, String k1,
String k2, String k3, String k4) {
this.settingsCacheService = settingsCacheService;
this.k1 = k1;
this.k2 = k2;
this.k3 = k3;
this.k4 = k4;
}
public static ActorRef getActor(ActorSystem remoteActorSystem, SettingsCacheService settingsCacheService,
String k1, String k2, String k3, String k4) {
return remoteActorSystem.actorOf(
Props.create(SettingsCacheEvictScheduler.class, settingsCacheService, k1, k2,
k3, k4));
}
@Override
public void onReceive(Object message) throws Throwable {
if (MESSAGE.equals(message)) {
settingsCacheService.cacheEvict(this, k1, k2, k3, k4);
}
}
}
我以调试模式运行该应用程序,并添加了Spring缓存的跟踪日志。 我可以看到在缓存中创建的值具有预期的由4个字符串组成的键。调度程序按预期方式工作,并按预期方式调用cacheEvict方法,但是缓存逐出不起作用,并且值仍保留在缓存中。
我可以看到此日志中的另一个缓存服务:
Invalidating cache key [myKey] for
,但永远不要使用此缓存服务。我没有看到拦截器需要设置缓存服务,而拦截器却需要其他缓存(我可以调试)。
我可以通过调试模式和日志确认使用期望的键缓存了值
CacheInterceptor - Computed cache key '[k1, k2, k3, k4]' for operation...
我可以看到cacheEvict方法内的代码已执行,但@cacheEvict批注似乎被忽略了
我有以下问题: 是否可以将这样的cacheEvict方法与由4个字符串组成的键一起使用? Akka是否存在任何不兼容性?
我用cachePut而不是cacheEvict尝试了同样的方法,并且遇到了同样的问题。