Skip to content

Provide a mechanism for composed annotations to signal that they want to override attributes [SPR-13448] #18028

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 9, 2015 · 3 comments
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: bulk-closed An outdated, unresolved issue that's closed in bulk as part of a cleaning process

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Sep 9, 2015

Dave Syer opened SPR-13448 and commented

AnnotatedElementUtils is now available for processing merged (overridden) attributes from meta-annotated custom annotations, but Spring doesn't use it uniformly (because of performance concerns). The one that bit me was an ImportBeanDefinitionRegistrar where the annotation was a custom one and the AnnotationMetadata that is passed in does not contain the overridden/inherited values.

The reason, it turns out, is that StandardAnnotationMetadata, while it uses AnnotatedElementUtils, explicitly chooses not to get the overridden attributes by invoking getAllAnnotationAttributes() instead of getMergedAnnotationAttributes() (and this is all that is directly available to the ImportBeanDefinitionRegistrar).

Maybe there's a way to address the performance concerns and use the deeper AnnotatedElementUtils.getMergedAnnotationAttributes() utility method(s) only if the user signals that the annotation needs to be processed this way -- for example, by introducing an annotation such as @Mergeable (or an explicit @AliasFor on the attribute).

See also: #18020


Affects: 4.2 GA

Issue Links:

0 votes, 6 watchers

@spring-projects-issues
Copy link
Collaborator Author

Dave Syer commented

There is a workaround for my current specific issue (because I control the ImportBeanDefinitionRegistrar), which is to use the more powerful method in AnnotatedElementUtils explicitly:

public class SomethingRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(AnnotationMetadata metadata,
			BeanDefinitionRegistry registry) {
		AnnotationAttributes attrs = AnnotatedElementUtils.getMergedAnnotationAttributes(
				ClassUtils.resolveClassName(metadata.getClassName(), null),
				EnableSomething.class);
		for (Class<?> type : collectClasses(attrs.get("value"))) {
			BeanDefinition beanDefinition = new RootBeanDefinition(type);
			registry.registerBeanDefinition("something", beanDefinition);
		}
	}

N.B. the custom annotation has to use @AliasFor on all its inherited attributes for this to work.

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Dave Syer,

I'm glad you found a work-around for the time being.

FYI: please note that getAllAnnotationAttributes() and getMergedAnnotationAttributes() actually have quite different semantics. getAllAnnotationAttributes() aggregates attributes across all annotations present above the annotated element; whereas, getMergedAnnotationAttributes() only merges attributes from a single branch in the annotation hierarchy.

This subtlety may not have any impact on your particular use case, but...

The reason I mention this difference is that getAllAnnotationAttributes() will find multiple instances of the target annotation (if present), but getMergedAnnotationAttributes() will only find one instance of the target annotation, ignoring any other instances of the target annotation that may be present. Typically, only @Profile and @Conditional require the "aggregate" semantics.

Make sense?

N.B. the custom annotation has to use @AliasFor on all its inherited attributes for this to work.

What do you mean by "all" in this context?

Are you saying that convention-based attribute overrides do not work? If so, then that's a bug, and please report it.

Cheers,

Sam

@spring-projects-issues spring-projects-issues added status: waiting-for-triage An issue we've not yet triaged or decided on type: enhancement A general enhancement in: core Issues in core modules (aop, beans, core, context, expression) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues removed the type: enhancement A general enhancement label Jan 11, 2019
@rstoyanchev rstoyanchev added status: bulk-closed An outdated, unresolved issue that's closed in bulk as part of a cleaning process and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 11, 2019
@spring-projects-issues
Copy link
Collaborator Author

Bulk closing outdated, unresolved issues. Please, reopen if still relevant.

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) status: bulk-closed An outdated, unresolved issue that's closed in bulk as part of a cleaning process
Projects
None yet
Development

No branches or pull requests

2 participants