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: - #17723 Support dynamic bean lookup a la CDI's Instance type - #13532 Convenient programmatic bean retrieval with qualifiers
2 votes, 4 watchers
Comment From: spring-projects-issues
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.
Comment From: spring-projects-issues
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?
Comment From: spring-projects-issues
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.
Comment From: SaiKrishnaKaushik
Hi Is this still a requirement and there is a need for it?