Skip to content
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

Explicit attribute overrides configured via @AliasFor not supported for components picked up via component scanning #23402

Closed
brucelwl opened this issue Aug 1, 2019 · 4 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: feedback-provided Feedback has been provided type: enhancement A general enhancement
Milestone

Comments

@brucelwl
Copy link

brucelwl commented Aug 1, 2019

I have a longer set of annotation attributes, so I use @AliasFor to set up a short annotation. If the new annotation is set on the boot class, the value of the annotation attributes can be obtained, but the value of the annotation attributes can not be obtained on the non-boot class
Maybe if you look at my demo, you can get a clearer understanding of what I mean.
https://github.com/brucelwl/demo

@snicoll snicoll transferred this issue from spring-projects/spring-boot Aug 2, 2019
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Aug 2, 2019
@sbrannen
Copy link
Member

sbrannen commented Aug 2, 2019

Thanks for raising the issue.

In your example, it turns out that @AliasFor is not honored for attribute override support in a meta-annotation when AnnotationMetadataReadingVisitor is the concrete implementation type for the AnnotationMetadata importingClassMetadata argument supplied to your registerBeanDefinitions() implementation.

In contrast, when the concrete implementation type is StandardAnnotationMetadata, your code works as expected.

So that at least explains what it is going on.

I don't yet have a workaround or solution to your problem, but we will continue to investigate.

@sbrannen sbrannen added the in: core Issues in core modules (aop, beans, core, context, expression) label Aug 2, 2019
@sbrannen
Copy link
Member

sbrannen commented Aug 2, 2019

@brucelwl, one way to circumvent the issue is to force the loading of @Configuration classes discovered via component scanning.

If you're OK with eagerly forcing the loading of such classes, the following should work for you in GitConfigBeanDefinitionRegistrar.

Basically, the goal in the following code is to:

  1. retrieve the fully qualified class name of the @Configuration class from the supplied metadata
  2. eagerly load the @Configuration class using reflection via ClassUtils
  3. use AnnotatedElementUtils for full support of @AliasFor, including support for attribute overrides in meta-annotations.
Class<?> clazz = null;
try {
	String className = importingClassMetadata.getClassName();
	clazz = ClassUtils.forName(className, null);
}
catch (ClassNotFoundException ex) {
	throw new RuntimeException(ex);
}
EnableGitVersionControlConfig anno =
	AnnotatedElementUtils.findMergedAnnotation(clazz, EnableGitVersionControlConfig.class);

logger.info("*** serverAddress={}", anno.serverAddress());
logger.info("*** targetBranch={}", anno.targetBranch());

When I execute your tests with the above change, I see the expected log output.

Please let me know if this workaround works for you!

Thanks,

Sam

@sbrannen sbrannen added the status: waiting-for-feedback We need additional information before we can continue label Aug 2, 2019
@brucelwl
Copy link
Author

brucelwl commented Aug 3, 2019

@sbrannen Thank you very much for your reply. Your solution can solve my problem. I have another similar solution.

public class GitConfigBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    private static final Logger logger = LoggerFactory.getLogger(GitConfigBeanDefinitionRegistrar.class);

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        String className = importingClassMetadata.getClassName();
        Class<?> aClass = null;
        try {
            aClass = ClassUtils.forName(className, null);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(aClass, true);
        AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(
                metadata.getAnnotationAttributes(EnableGitVersionControlConfig.class.getName()));
        logger.info("serverAddress={}", annotationAttributes.getString("serverAddress"));
        logger.info("targetBranch={}", annotationAttributes.getString("targetBranch"));
    }
}

@brucelwl brucelwl closed this as completed Aug 3, 2019
@sbrannen sbrannen changed the title Annotations with @AliasFor are invalid in non-startup classes Explicit attribute overrides configured via @AliasFor not supported for components picked up via component scanning Aug 9, 2019
@sbrannen sbrannen added status: feedback-provided Feedback has been provided type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on status: waiting-for-feedback We need additional information before we can continue labels Aug 9, 2019
@sbrannen sbrannen added this to the 5.2 RC2 milestone Aug 9, 2019
@sbrannen
Copy link
Member

sbrannen commented Aug 9, 2019

@brucelwl, thank you for the confirmation! I am glad to know that works for you.

FWIW, the behavior you described is a known deficiency.

Fortunately, @philwebb resolved this issue for the upcoming Spring Framework 5.2 release. This was achieved by the introduction of a new SimpleAnnotationMetadata class that is used behind the scenes for components picked up via component scanning. SimpleAnnotationMetadata uses the new MergedAnnotations API which provides full support for @AliasFor within annotation hierarchies, even for metadata sourced from ASM.

I have therefore changed the title of this issue to reflect the known deficiency, and I've assigned this issue to 5.2 so that others know that this has been addressed.

Thanks again, @philwebb, for SimpleAnnotationMetadata and (unwittingly?) fixing this issue!

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: feedback-provided Feedback has been provided type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants