gpt4 book ai didi

java - 自定义 CacheResolver 不工作

转载 作者:搜寻专家 更新时间:2023-10-31 20:33:37 25 4
gpt4 key购买 nike

我有一个带有自定义 CacheResolver 的 Spring Boot 项目,因为我需要在运行时决定我想使用哪个缓存,我没有任何编译错误,但是当我做一些测试和在我的自定义 CacheResolver 中放置一个断点,它永远不会进入它。

这是我的缓存配置类:

@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);
}
}

这是我的缓存解析器

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;
}
}

这是我使用缓存的 DAO:

    @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
}
.
.
.
}

我已经尝试实现 CacheResolver 而不是扩展 AbstractCacheResolver 但它没有任何区别。

谢谢。

最佳答案

有时需要包含缓存名称,仅指定要使用的 CacheResolver 是不够的,@Cacheable 类需要知道可用的缓存名称,所以我将它们包含在 @CacheConfig 注释中:

@CacheConfig(cacheNames = {WgstCacheConfig.PERMANENT_CACHE, WgstCacheConfig.SIZED_CACHE},
cacheResolver = WgstCacheConfig.WGST_CACHE_RESOLVER)
public class CacheableDao<T extends Storable> extends AbstractDao<T> {

我不喜欢的一件事是我需要提供一个 null CacheManager,即使我没有使用它,否则我会收到以下错误:

Caused by: java.lang.IllegalStateException: No CacheResolver specified, and no bean of type CacheManager found. Register a CacheManager bean or remove the @EnableCaching annotation from your configuration.

所以我就这样保留了它,它起作用了:

  @Bean
public CacheManager cacheManager() {
return null;
}

@Bean(name = WGST_CACHE_RESOLVER)
public CacheResolver cacheResolver(){
CacheResolver cacheResolver = new WgstCacheResolver(cacheableDocuments(),sizedCacheableDocuments(),getPermanentCache(),
getSizedCache());
return cacheResolver;
}

重新运行我的测试,单步执行我的自定义 CacheResolver,它的行为符合预期,解析为正确的缓存

我的配置类不再扩展 CachingConfigurerSupport

关于java - 自定义 CacheResolver 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30456107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com