Skip to content

Support composed annotations declared on interfaces [SPR-11108] #15734

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 Nov 22, 2013 · 6 comments
Closed
Labels
in: core Issues in core modules (aop, beans, core, context, expression) in: data Issues in data modules (jdbc, orm, oxm, tx) in: test Issues in the test module status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Nov 22, 2013

Sam Brannen opened SPR-11108 and commented

Status Quo

The findAnnotation() methods in AnnotationUtils currently support searching for meta-annotations declared on composed annotations that are declared on interfaces; however, various parts of the framework -- for example, code that relies on AnnotationAttributes - only support composed annotations on classes or methods (not on interfaces or interface methods).

For example, given the following:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(rollbackFor=Exception.class, noRollbackFor={IOException.class})
public @interface TxWithAttribute {

	boolean readOnly();
}

@TxWithAttribute(readOnly = true)
public static interface TestInterface9 {

	public int getAge();
}

public static class TestBean9 implements TestInterface9 {

	@Override
	public int getAge() {
		return 10;
	}
}

public static interface TestInterface10 {

	@TxWithAttribute(readOnly=true)
	public int getAge();
}

public static class TestBean10 implements TestInterface10 {

	@Override
	public int getAge() {
		return 10;
	}
}

Spring's support for resolving transaction attributes (e.g., the AbstractFallbackTransactionAttributeSource.computeTransactionAttribute() to SpringTransactionAnnotationParser.parseTransactionAnnotation() call stack) fails to find @Transactional which is declared via @TxWithAttribute on interfaces.

Proposal

Introduce support for composable stereotype annotations declared on interfaces.


Affects: 4.0 RC1

Issue Links:

1 votes, 3 watchers

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

To reproduce this lacking support, see the customClassAttributeWithReadOnlyOverrideOnInterface() and customMethodAttributeWithReadOnlyOverrideOnInterface() tests introduced in AnnotationTransactionAttributeSourceTests from GitHub commit ad402dc.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Good point. Alright, let's try to roll this into 4.0 RC2 still...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Sam, this doesn't seem to have much to do with AnnotationAttributes or the like...

It's rather that we generally only detect @Transactional annotations on an interface if the invocation comes in through that interface. So in those unit tests, you simply need to pass in the interface method instead of the target class method (which I've just changed and committed). If that's the case, both direct lookups and meta-annotation lookups work. So with JDK proxies, all should be fine. With CGLIB proxies, neither of those two variants works - just like before. It's generally arguable whether CGLIB proxies should also check interfaces there, but anyway, it doesn't seem to be an inconsistency between direct and meta use of @Transactional.

Let me know if I'm missing something...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Juergen, just to recap on our discussion...

I mentioned support for @Transactional only as an example to demonstrate the issue. The crux of the issue is described in the opening sentence:

The findAnnotation() methods in AnnotationUtils currently support searching for meta-annotations declared on composed annotations that are declared on interfaces; however, various parts of the framework -- for example, code that relies on AnnotationAttributes - only support composed annotations on classes or methods (not on interfaces or interface methods).

So there is in fact a difference in the behavior of AnnotatedElementUtils and AnnotationUtils with regard to traversal of interfaces. Whether or not this difference poses an actual problem for end users' code at runtime will require further analysis of current use of AnnotationAttributes, AnnotatedElementUtils, etc. across the code base.

Regards,

Sam

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Apr 22, 2015

Sam Brannen commented

Update: #17300 covers interface support in AnnotatedElementUtils; however, I am leaving this issue open for the time being in order to ensure we cover the same use cases for Spring's ASM-based annotation processing support (e.g., AnnotationAttributesReadingVisitor, etc.).

@sbrannen
Copy link
Member

No issues have been reported related to this topic in almost 10 years. In addition, we have since switched to a MergedAnnotations-based implementation for our ASM support in the org.springframework.core.type.classreading package.

In light of that, I am closing this issue.

@sbrannen sbrannen closed this as not planned Won't fix, can't repro, duplicate, stale Mar 25, 2025
@sbrannen sbrannen added the status: declined A suggestion or change that we don't feel we should currently apply label Mar 25, 2025
@sbrannen sbrannen removed this from the General Backlog milestone Mar 25, 2025
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) in: data Issues in data modules (jdbc, orm, oxm, tx) in: test Issues in the test module status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants