【问题标题】:spring cache with custom cacheResolver带有自定义 cacheResolver 的 spring 缓存
【发布时间】:2015-03-11 11:23:35
【问题描述】:

我希望有动态缓存名称,并且 spring 4.1 allows that

从 Spring 4.1 开始,缓存注解的 value 属性不再是强制性的,因为无论注解的内容如何,​​CacheResolver 都可以提供此特定信息。

注意我是如何在所有可能的级别上偏执地设置cacheResolver

@Cacheable(cacheResolver = "defaultCacheResolver")
@CacheConfig(cacheResolver = "defaultCacheResolver")
public interface GatewayRepository extends CrudRepository<Gateway, Integer> {
    @Cacheable(cacheResolver = "defaultCacheResolver")
    Gateway findByBulkId(int bulkId);
}

Spring 4.1.5 仍然无法验证配置并出现错误:Caused by: java.lang.IllegalStateException: No cache names could be detected on 'public abstract skunkworks.data.Gateway skunkworks.repos.GatewayRepository.findByBulkId(int)'. Make sure to set the value parameter on the annotation or declare a @CacheConfig at the class-level with the default cache name(s) to use. at org.springframework.cache.annotation.SpringCacheAnnotationParser.validateCacheOperation(SpringCacheAnnotationParser.java:240)

【问题讨论】:

  • 如果你删除所有这些并且在方法上只使用一个简单的@Cacheable 会发生什么?看起来注释隐藏在代理或其他东西后面。如果我是你,我会在 SD 存储库上使用 ORM 二级缓存支持。
  • 普通缓存配置有效。我查看了spring代码,它正确读取了cacheResolver,但验证失败。对我来说,这看起来像是一个 Spring 错误,但太明显了。
  • 我对你如何到达那里感到有点困惑。如果您有一个项目可以重现您的问题,请创建一个问题(jira.spring.io/browse/SPR),我们会看看。我们很快就会发布 4.1.6,所以请尽快发布。

标签: spring spring-data spring-cache


【解决方案1】:

我认为您应该在代码中的某处指定缓存名称。

在基本用法中,缓存名称在@Cacheable、@CachePut 或@CacheEvict 注解中给出。

@Cacheable(cacheNames = "myCache")

您也可以在@CacheConfig 中指定它,这是一个类级别的注释。

@CacheConfig(cacheNames = "myCache")

如果需要更灵活的缓存机制,可以使用CacheResolver。在这种情况下,您应该创建自己的 CacheResolver。大致如下:

public class CustomCacheResolver implements CacheResolver {

    private final CacheManager cacheManager;

    public CustomCacheResolver(CacheManager cacheManager){
        this.cacheManager = cacheManager;
    }

    @Override
    public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
        Collection<Cache> caches = new ArrayList<>();
        if(context.getTarget().getClass() == GatewayRepository.class){
            if(context.getMethod().getName().equals("findByBulkId")){
                caches.add(cacheManager.getCache("gatewayCache"));
            }
        }

        return caches;
    }
}

在这一步中,缓存名称为

网关缓存

只在cacheresolver中定义,注解端可以省略。

在这一步之后,你应该注册CacheResolver:

@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport {

    @Bean
    @Override
    public CacheManager cacheManager() {
         // Desired CacheManager
    }

    @Bean
    @Override
    public CacheResolver cacheResolver() {
        return new CustomCacheResolver(cacheManager());
    }
}

作为最后一步,您应该在 @Cacheable、@CachePut、@CacheConfig 等注释之一中指定 CustomCacheResolver。

@Cacheable(cacheResolver="cacheResolver")

您可以查看here 的代码示例

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-15
    • 2021-06-27
    • 1970-01-01
    • 2014-09-03
    相关资源
    最近更新 更多