Add Qualified element on RootBeanDefinition

Improve RootBeanDefinition to specify an AnnotatedElement that holds
qualifier information. When such element is present, any qualifier that
it defines will be used to find a matching candidate.

Issue: SPR-14725
This commit is contained in:
Stephane Nicoll
2016-09-15 16:02:10 +02:00
parent f24ce76edb
commit 2b0bf9f04a
4 changed files with 68 additions and 9 deletions

View File

@@ -17,6 +17,7 @@
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Map;
@@ -49,6 +50,7 @@ import org.springframework.util.StringUtils;
*
* @author Mark Fisher
* @author Juergen Hoeller
* @author Stephane Nicoll
* @since 2.5
* @see AutowireCandidateQualifier
* @see Qualifier
@@ -225,8 +227,12 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
qualifier = bd.getQualifier(ClassUtils.getShortName(type));
}
if (qualifier == null) {
// First, check annotation on factory method, if applicable
Annotation targetAnnotation = getFactoryMethodAnnotation(bd, type);
// First, check annotation on qualified element, if any
Annotation targetAnnotation = getQualifiedElementAnnotation(bd, type);
// Then, check annotation on factory method, if applicable
if (targetAnnotation == null) {
targetAnnotation = getFactoryMethodAnnotation(bd, type);
}
if (targetAnnotation == null) {
RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
if (dbd != null) {
@@ -291,6 +297,11 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
return true;
}
protected Annotation getQualifiedElementAnnotation(RootBeanDefinition bd, Class<? extends Annotation> type) {
AnnotatedElement qualifiedElement = bd.getQualifiedElement();
return (qualifiedElement != null ? AnnotationUtils.getAnnotation(qualifiedElement, type) : null);
}
protected Annotation getFactoryMethodAnnotation(RootBeanDefinition bd, Class<? extends Annotation> type) {
Method resolvedFactoryMethod = bd.getResolvedFactoryMethod();
return (resolvedFactoryMethod != null ? AnnotationUtils.getAnnotation(resolvedFactoryMethod, type) : null);

View File

@@ -16,6 +16,7 @@
package org.springframework.beans.factory.support;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Executable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
@@ -58,6 +59,8 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
boolean isFactoryMethodUnique = false;
volatile AnnotatedElement qualifiedElement;
/** Package-visible field for caching the determined Class of a given bean definition */
volatile Class<?> resolvedTargetType;
@@ -182,6 +185,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
this.allowCaching = original.allowCaching;
this.targetType = original.targetType;
this.isFactoryMethodUnique = original.isFactoryMethodUnique;
this.qualifiedElement = original.qualifiedElement;
}
/**
@@ -257,6 +261,22 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
this.isFactoryMethodUnique = true;
}
/**
* Specify the {@link AnnotatedElement} defining qualifiers.
* @since 4.3.3
*/
public void setQualifiedElement(AnnotatedElement qualifiedElement) {
this.qualifiedElement = qualifiedElement;
}
/**
* Return the {@link AnnotatedElement} defining qualifiers, if any.
* @since 4.3.3
*/
public AnnotatedElement getQualifiedElement() {
return this.qualifiedElement;
}
/**
* Check whether the given candidate qualifies as a factory method.
*/