Ich habe ein Spring Boot-Projekt mit einem benutzerdefinierten CacheResolver
, da ich zur Laufzeit entscheiden muss, welchen Cache ich verwenden möchte, ich habe keine Kompilierungsfehler, aber wenn ich einige Tests mache und eine Pause mache Punkt auf meine benutzerdefinierte CacheResolver
es tritt nie in es.Benutzerdefinierte CacheResolver funktioniert nicht
Dies ist meine Konfigurationsklasse für den Cache:
@Configuration
@EnableCaching(proxyTargetClass = true)
@PropertySource(CacheConfig.CLASSPATH_DEPLOY_CACHE_PROPERTIES_PROPERTIES)
public class CacheConfig extends CachingConfigurerSupport{
public static final String CLASSPATH_DEPLOY_CACHE_PROPERTIES_PROPERTIES = "classpath:/deploy/cache-properties.properties";
public static final String CACHEABLE_DOCUMENTS_PROPERTY = "cacheable.documents";
public static final String TTL_CACHEABLE_DOCUMENTS_PROPERTY = "ttl.cacheable.documents";
public static final String SIZED_CACHEABLE_DOCUMENTS_PROPERTY = "sized.cacheable.documents";
public static final String CACHE_NAME = "permanentCache";
public static final String TTL_CACHE = "ttlCache";
public static final String SIZED_CACHE = "sizedCache";
public static final String CACHEABLE_DOCUMENTS = "cacheableDocuments";
public static final String SIZED_CACHEABLE_DOCUMENTS = "sizedCacheableDocuments";
public static final int WEIGHT = 1000000;
public static final int TO_KBYTES = 1000;
@Inject
protected Environment environment;
//@Bean
@Override
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
GuavaCache sizedCache = new GuavaCache(SIZED_CACHE, CacheBuilder.newBuilder().maximumWeight(WEIGHT).weigher(
(key, storable) -> {
String json = ((Storable) storable).toJson();
return json.getBytes().length/TO_KBYTES;
}
).build());
GuavaCache permanentCache = new GuavaCache(CACHE_NAME,CacheBuilder.newBuilder().build());
//GuavaCache ttlCache = new GuavaCache(TTL_CACHE, CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).build());
cacheManager.setCaches(Arrays.asList(permanentCache,sizedCache));
return cacheManager;
}
@Bean(name = "wgstCacheResolver")
@Override
public CacheResolver cacheResolver(){
CacheResolver cacheResolver = new WgstCacheResolver(cacheManager(),cacheableDocuments(),sizedCacheableDocuments());
return cacheResolver;
}
@Bean(name = CACHEABLE_DOCUMENTS)
public List<String> cacheableDocuments(){
String[] cacheableDocuments = StringUtils.commaDelimitedListToStringArray(environment.getProperty(CACHEABLE_DOCUMENTS_PROPERTY));
return Arrays.asList(cacheableDocuments);
}
@Bean(name = SIZED_CACHEABLE_DOCUMENTS)
public List<String> sizedCacheableDocuments(){
String[] sizedCacheableDocuments = StringUtils.commaDelimitedListToStringArray(environment.getProperty(SIZED_CACHEABLE_DOCUMENTS_PROPERTY));
return Arrays.asList(sizedCacheableDocuments);
}
}
Hier ist meine CacheResolver
public class WgstCacheResolver extends AbstractCacheResolver {
private final List<String> cacheableDocuments;
private final List<String> sizedCacheableDocuments;
public WgstCacheResolver(final CacheManager cacheManager,final List<String> cacheableDocuments, final List<String> sizedCacheableDocuments) {
super(cacheManager);
this.cacheableDocuments = cacheableDocuments;
this.sizedCacheableDocuments = sizedCacheableDocuments;
}
/**
* Resolves the cache(s) to be updated on runtime
* @param context
* @return*/
@Override
protected Collection<String> getCacheNames(final CacheOperationInvocationContext<?> context) {
final Collection<String> cacheNames = new ArrayList<>();
final AbstractDao dao = (AbstractDao)context.getTarget();
final String documentType = dao.getDocumentType().toString();
if (cacheableDocuments.contains(documentType)){
cacheNames.add("permanentCache");
}
if (sizedCacheableDocuments.contains(documentType)){
cacheNames.add("sizedCache");
}
return cacheNames;
}
}
Und hier meine DAO, wo ich den Cache verwenden:
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.DEFAULT)
@CacheConfig(cacheResolver = "wgstCacheResolver")
public class CacheableDao<T extends Storable> extends AbstractDao<T> {
private final Logger logger = LoggerFactory.getLogger(CacheableDao.class);
public CacheableDao(final Bucket bucket, final Class<T> typeParameterClass, final DocumentType documentType) {
super(bucket, typeParameterClass, documentType);
}
@Cacheable(key = "{#root.methodName, #root.target.generateFullKey(#key)}")
public T get(final String key) throws DatastoreAccessException, ObjectMappingException {
//do something
}
.
.
.
}
Ich habe versucht, CacheResolver
zu implementieren, anstatt AbstractCacheResolver
zu erweitern, aber es hat nicht mak Irgendein Unterschied.
Vielen Dank.
Nun, Sie haben keinen Cache-Namen dort, so wenn Caching funktioniert, muss es den Cache-Namen auflösen, sonst wird es eine Ausnahme werfen. Meine beste Vermutung ist, dass Caching überhaupt nicht funktioniert. Ihre Konfiguration ist auch sehr _weird_. Sie verwenden 'CachingConfiguration', um den _default_' CacheResolver' bereitzustellen, so dass Sie ihn gar nicht angeben müssen. Wenn Sie es pro Vorgang (mit einem speziellen Namen) angeben möchten, definieren Sie es anderswo (nicht als Standard). –
Danke @ stéphane-nicoll, du hast mich in die richtige Richtung gelenkt, ich habe das Problem behoben, indem ich die Cache-Namen mit der 'CacheConfig'-Annotation eingefügt habe, meine Tests durchgeführt und Fehler gemacht habe und nun funktioniert der'CacheResolver' wie erwartet. Ich nahm an, dass Cache-Namen nicht enthalten sein müssten, da der 'CacheResolver' dort war. – tommylii
Gern geschehen, aber die Cache-Namen werden nicht benötigt. Wie gesagt, wenn Ihr Cache-Resolver nicht aufgerufen wurde und Sie keine Ausnahme hatten, hatten Sie wahrscheinlich überhaupt kein Caching. Die folgende Antwort ist falsch (es sei denn, es gibt einen Fehler) –