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

Ability to query an ApplicationContext for annotations on a bean [SPR-12929] #17522

Closed
spring-projects-issues opened this issue Apr 18, 2015 · 4 comments
Labels
in: core Issues in core modules (aop, beans, core, context, expression) 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 Apr 18, 2015

Andres Almiray opened SPR-12929 and commented

Currently the ApplicationContext is capable of resolving beans and beans names given an annotation but the reverse is not, that is, obtain an annotation given a bean name.

Currently annotation metadata is harvested and stored in org.springframework.core.type.AnnotationMetadata but the actual annotation is not.

For reference, this feature was discussed with Jürgen at Voxxed Days Ticino 2015 in the context of a generic, external JSR-330 compatible API on top of Spring and Guice.


Affects: 4.1.6

Issue Links:

2 votes, 4 watchers

@spring-projects-issues
Copy link
Collaborator Author

Andres Almiray commented

Harvesting qualifier information related to a bean or a set of beans can be done in the following way (a bit cumbersome but possible)

AutowireCapableBeanFactory autowireCapableBeanFactory = appContext.getAutowireCapableBeanFactory();
if (autowireCapableBeanFactory instanceof BeanDefinitionRegistry) {
    BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) autowireCapableBeanFactory;
    for (String beanDefinitionName : appContext.getBeanNamesForType(type)) {
        BeanDefinition beanDefinition = beanDefinitionRegistry.getBeanDefinition(beanDefinitionName);
        AnnotatedGenericBeanDefinition agbd = (AnnotatedGenericBeanDefinition) beanDefinition;
        AutowireCandidateQualifier qualifier = null;
        Set<AutowireCandidateQualifier> qualifiers = agbd.getQualifiers();
        if (qualifiers != null && qualifiers.size() > 0) {
            qualifier = qualifiers.iterator().next();
        }
        AnnotationMetadata metadata = agbd.getMetadata();
        // ???
    }
}

Two problems appear here:

  1. one must rely on explicit implementations (such as BeanDefinitionRegistry and AnnotatedGenericBeanDefinition) to reach the annotation metadata.
  2. AnnotationMetadata contains all information pertaining qualifiers but does not have a link to the annotations that provided such information.

I wish it was possible to reach out for AnnotationMetadata directly from a BeanDefinition instance.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Jan 17, 2017

Juergen Hoeller commented

I'm afraid it's even less natural for Spring 5 to store and expose annotation instances than before. We do intend to introduce new retrieval facilities but primarily for functional-style filtering: #13532. Internally, we remain rather agnostic to annotation instances and process specific annotation metadata for our purposes only, which I'd like to keep up.

Rather than downcasting BeanDefinitions, a call getType for each such bean name returns a Class which can be introspected for type-level annotations meta-annotated with @Qualifier (or the like). Admittedly, this won't work for qualifiers on @Bean methods; is this the missing part here? How does the corresponding lookup work for Guice?

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Jan 18, 2017

Andres Almiray commented

In Guice, every com.google.inject.Binding is referenced by a com.google.inject.Key that contains the injection type and an optional annotation. A Key matches the type and annotation at a point of injection. Say you want to define a bean of type Person annotated with @Named, you could do it in the following way inside a Module:

public class MyModule extends AbstractModule {
  public void configure(Binder binder) {
    binder.bind(Person.class)
              .annotatedWith(Named.class);
  }
}

In a sense, explicit Module configuration in Guice is similar to Spring's Java config via @Configuration and @Bean. Guice also supports "on-demand" bindings, that is, if a type is required but is not defined by a Module, and if the type can be found then an implicit binding is created. this is similar to Spring's @Component support.

Being able to query annotations that may have been defined in the target type (option # 2 via @Component) and in the config class (option # 1 via @Bean) is exactly what I need to write a "native" Spring based injector that can define bindings programmatically and harvest existing types/annotations. My current workaround to support Spring on Grifofn is to leverate spring-guice https://github.com/spring-projects/spring-guice This project wraps an ApplicationContext within a Module. As the documentation says it does not cover all cases and registers all beans eagerly.

@spring-projects-issues spring-projects-issues added 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 added this to the 5.x Backlog milestone Jan 11, 2019
@jhoeller jhoeller modified the milestones: 5.x Backlog, General Backlog Aug 24, 2020
@SaiKrishnaKaushik
Copy link

Hi Is this still a requirement and there is a need for it?

@jhoeller jhoeller added the status: declined A suggestion or change that we don't feel we should currently apply label Jul 13, 2023
@jhoeller jhoeller removed this from the General Backlog milestone Jul 13, 2023
@sbrannen sbrannen closed this as not planned Won't fix, can't repro, duplicate, stale Jul 13, 2023
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: 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

4 participants