编写自定义的Spring @Cacheable注解

3
我目前正在编写一个自定义的@Cacheable注解,它将提供额外的元数据属性,除了Spring的@Cacheable注解提供的。然而,Spring需要知道如何解析这个新注解。我理解的是,我需要扩展并覆盖AnnotationCacheOperationSourcedetermineCacheOperations()方法,以便可以使用适当的CacheableOperation类来从中初始化新注解。这是否是正确的操作方式?
谢谢,
Steve

2
@Steve,你的问题解决了吗?如果是这样,能否分享一下解决方法。我也遇到了这个问题。感谢你在此方面提供的帮助。 - Mari
1个回答

2

取决于情况。

根据AnnotationCacheOperationSource javadoc

该类读取Spring的Cacheable、CachePut和CacheEvict注释,并将相应的缓存操作定义公开给Spring的缓存基础设施。该类还可以用作自定义CacheOperationSource的基类。

因此,如果您要求是否可以扩展该类以获得CacheOperationSource的扩展行为,则答案是肯定的。

但是,determineCacheOperations()方法所做的是使用所有可用的CacheAnnotationParsers。唯一的默认CacheAnnotationParser是SpringCacheAnnotationParser。如果您有自定义的CacheAnnotationParser,请使用另一个实现CacheAnnotationParser的类。Spring应该会自动使用它。您可以查看SpringCacheAnnotationParser源代码,了解它们如何实现。


编辑:好吧,我错了,这不会自动发生。我的下一个建议是:

  • 实现CacheAnnotationParser接口,就像您已经做的那样
  • 扩展AnnotationCacheOperationSource,以便将自己的CacheAnnotationParser放入内部解析器集合中,除了Spring之外
  • 定义您自己的自定义AnnotationCacheOperationSource,以使用与Spring相同的id,因此它将覆盖Spring内部。如果id匹配,则应该干净地覆盖Spring。这将类似于:

    <bean id="annotationCacheOperationSource" class="com.company.YourCustomAnnotationCacheOperationSource" />


非常感谢您的回复Eis。我已经考虑过将SpringCacheAnnotationParser的parseCacheableAnnotation()方法复制到新的扩展AnnotationCacheOperationSource中,但是您的方法更加清晰和规范,通过将其抽象成单独的CacheAnnotationParser。我是否需要在Spring中注册新的CacheAnnotationParser以便它被识别,并且我该如何做到这一点? - SNK
@Steve,Spring 的工作方式通常是您只需实现所需的接口,然后将实现该接口的类作为 bean 在 Spring 上下文中进行连接。然后根据接口自动正确使用它。我认为这也适用于此情况。 - eis
我不能让新的CacheAnnotationParser被识别。我正在使用cache:annotation-driven在我的配置文件中,在初始化期间,AnnotationDrivenCacheBeanDefinitionParser创建了一个AnnotationCacheOperationSource,它使用单个SpringCacheAnnotationParser。我认为的解决方案是在我的配置文件中定义一个AnnotationCacheOperationSource、CacheInterceptor和BeanFactoryCacheOperationSourceAdvisor(一个cacheAdvisor),这将初始化新的pasrer。但问题是我们会有两个AnnotationCacheOperationSource bean被创建;一个是由Spring创建的,另一个是由我的应用程序创建的。任何帮助都将不胜感激。 - SNK
@Steve 你用的是哪个版本的Spring呀?顺便问一下。 - eis
@Steve现在更新了我的答案,并提出了另一个建议。 - eis
谢谢Eis。我已经完成了我的AnnotationCacheOperationSource。如你所说,我定义了一个annotationCacheOperationSource bean以及cacheInterceptor(org.springframework.cache.interceptor.CacheInterceptor)和cacheAdvisor(org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor)。这三个bean似乎可以一起使用,通过定义它们,所有的事情都解决了。遗憾的是,仅有bean annotationCacheOperationSource是行不通的(Spring没有识别它),必须定义cacheInterceptor和cacheAdvisor。希望我做得没问题 :) - SNK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接