Skip to content

Support @Cache* as merged composed annotations [SPR-13475] #18054

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Sep 20, 2015 · 8 comments
Closed
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Sep 20, 2015

Nicolas Labrot opened SPR-13475 and commented

Given this composed annotation:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Cacheable
public @interface MyCacheable {
	String[] cacheNames() default {};
	String key() default "";
}

The resulting @Cacheable attributes are not merged. Issue seems to come from SpringCacheAnnotationParser#parseCacheAnnotations which does not use AnnotatedElementUtils.findMergedAnnotation(*, Cacheable.class);.


Affects: 4.2 GA

Issue Links:

Referenced from: commits ea09e57, 59c88eb, 54703bf

1 votes, 7 watchers

@spring-projects-issues
Copy link
Collaborator Author

Stéphane Nicoll commented

Can you share a project that reproduces the problem because we have tests for that stuff.

Composable annotations may not work indeed but meta-annotations should.

@spring-projects-issues
Copy link
Collaborator Author

Stéphane Nicoll commented

Alright, scratch that. The merging thing isn't tested. I'll look at that in time for 4.2.2.RELEASE

@spring-projects-issues
Copy link
Collaborator Author

Nicolas Labrot commented

If you agree, I can give it a try to a PR.

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Nicolas Labrot, there's no need to create a PR for this, since it's straightforward.

Cheers,

Sam

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Sep 22, 2015

Sam Brannen commented

Hi guys,

I unfortunately spoke too soon: this is actually not straightforward.

The code in question is SpringCacheAnnotationParser.getAnnotations() which collects all annotations of the desired type (e.g., @Cacheable, @CacheEvict, etc.) present or meta-present on the annotated element.

In other words, even though Spring's caching annotations are not @Repeatable it is in fact possible to declare multiple instances of a given annotation if one or more such annotations are meta-present -- for example:

@Retention(RUNTIME)
@Target(METHOD)
@CacheEvict("foo")
public @interface EvictFoo {

	@AliasFor(annotation = Cacheable.class, attribute = "key")
	String key() default "";
}

@Retention(RUNTIME)
@Target(METHOD)
@CacheEvict("bar")
public @interface EvictBar {

	@AliasFor(annotation = Cacheable.class, attribute = "key")
	String key() default "";
}

@EvictFoo(key = "#id + 'foo'")
@EvictBar(key = "#id + 'bar'")
public void multipleEvictions(Long id) {}

Since AnnotatedElementUtils.findMergedAnnotation(...) finds a single target annotation, it is therefore (currently) impossible to support both @EvictFoo and @EvictBar as merged composed annotations on a single annotated element like the multipleEvictions() method above.

In conclusion: supporting @Cache\* annotations as merged composed annotations will require new functionality in AnnotatedElementUtils and extensive testing. As a consequence, I am pushing this off until Spring Framework 4.3.

Regards,

Sam

p.s. I have raised #17490 to address the missing functionality.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 20, 2016

Sam Brannen commented

FYI: #17490 has now been resolved.

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Completed as described in GitHub commit 59c88eb:

Support @Cache* as merged composed annotations

Prior to this commit, @Cacheable, @CacheEvict, @CachePut, and @Caching
could be used to create custom stereotype annotations with hardcoded
values for their attributes; however, it was not possible to create
composed annotations with attribute overrides.

This commit addresses this issue by refactoring
SpringCacheAnnotationParser to use the newly introduced
findAllMergedAnnotations() method in AnnotatedElementUtils. As a
result, @Cacheable, @CacheEvict, @CachePut, and @Caching can now be
used to create custom composed annotations with attribute overrides
configured via @AliasFor.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Oct 6, 2016

Marc Vanbrabant commented

Sam Brannen could it be that the refactoring from 59c88eb has broken some @CacheConfig configurations? I have created a (hopefully clear enough) bug report at #19347

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants