3

I'm currently writing a custom @Cacheable annotation that will take additonal meta-data attributes in addition to those that Spring's @Cacheable provides. However, Spring would need to know how to parse this new annotation. My understanding is that I'd need to extend and override AnnotationCacheOperationSource's determineCacheOperations() so that the new annotation can be parsed with an appropriate CacheableOperation class initialized from it. Is this the correct way to proceed?

Regards,

Steve

1
  • 2
    @Steve, Is your problem is solved, if so can you please share it. i am also blocked by this issue. Thanks for your help on this Commented Dec 10, 2017 at 6:46

1 Answer 1

2

Depends.

As per AnnotationCacheOperationSource javadoc,

This class reads Spring's Cacheable, CachePut and CacheEvict annotations and exposes corresponding caching operation definition to Spring's cache infrastructure. This class may also serve as base class for a custom CacheOperationSource.

So if you're asking for yes/no answer if you can extend that class for an extended behaviour of CacheOperationSource, the answer is yes.

However, what determineCacheOperations() method does is that it uses all the available CacheAnnotationParsers. The only default CacheAnnotationParser is SpringCacheAnnotationParser. If you have a custom one, just have another class implementing CacheAnnotationParser for your annotation. Spring should then use it automatically. You can take a look at the SpringCacheAnnotationParser source code to see how they do it.


Edit: ok, I was wrong in that this would happen automatically. My next suggestion is to

  • implement the interface CacheAnnotationParser, like you apparently already did
  • extend AnnotationCacheOperationSource so that you put your own CacheAnnotationParser in addition to Spring one in the internal parsers collection
  • define your custom AnnotationCacheOperationSource to use the same id as Spring one does, so it will override Spring internal. If id matches, it should override Spring one cleanly. This would be something like:

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

Sign up to request clarification or add additional context in comments.

6 Comments

Many thanks for the reply Eis. I had already thought of copying the parseCacheableAnnotation() method of SpringCacheAnnotationParser into the new extended AnnotationCacheOperationSource but your approach is much cleaner and proper by abstracting it into a separate CacheAnnotationParser. Wouldn't I need to register the new CacheAnnotationParser with Spring in order for it to be recognised and how could I do this?
@Steve the way spring works in general is that you just implement the required interface and then wire your class that implements it as a bean in spring context. It is then automatically used correctly based on the interface. I would think that applies to this case as well.
I can't get the new CacheAnnotationParser to be recognised. I'm using cache:annotation-driven in my config and during init the AnnotationDrivenCacheBeanDefinitionParser creates a AnnotationCacheOperationSource that uses a single SpringCacheAnnotationParser. A solution I think is to define a AnnotationCacheOperationSource, CacheInterceptor, and BeanFactoryCacheOperationSourceAdvisor (a cacheAdvisor) within my config which would init the new pasrer. But what we have then are 2 AnnotationCacheOperationSource beans created; one by Spring and one by my app. Any help is appreciated.
@Steve which spring version are you using, btw?
@Steve updated my answer now with another suggestion
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.