Fixed detection of qualifier annotations on scoped-proxy factory methods
Issue: SPR-11116
This commit is contained in:
@@ -26,7 +26,9 @@ import org.springframework.beans.SimpleTypeConverter;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateResolver;
|
||||
@@ -227,18 +229,22 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan
|
||||
|
||||
Class<? extends Annotation> type = annotation.annotationType();
|
||||
RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition();
|
||||
|
||||
AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());
|
||||
if (qualifier == null) {
|
||||
qualifier = bd.getQualifier(ClassUtils.getShortName(type));
|
||||
}
|
||||
if (qualifier == null) {
|
||||
Annotation targetAnnotation = null;
|
||||
Method resolvedFactoryMethod = bd.getResolvedFactoryMethod();
|
||||
if (resolvedFactoryMethod != null) {
|
||||
targetAnnotation = AnnotationUtils.getAnnotation(resolvedFactoryMethod, type);
|
||||
// First, check annotation on factory method, if applicable
|
||||
Annotation targetAnnotation = getFactoryMethodAnnotation(bd, type);
|
||||
if (targetAnnotation == null) {
|
||||
RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
|
||||
if (dbd != null) {
|
||||
targetAnnotation = getFactoryMethodAnnotation(dbd, type);
|
||||
}
|
||||
}
|
||||
if (targetAnnotation == null) {
|
||||
// look for matching annotation on the target class
|
||||
// Look for matching annotation on the target class
|
||||
if (this.beanFactory != null) {
|
||||
Class<?> beanType = this.beanFactory.getType(bdHolder.getBeanName());
|
||||
if (beanType != null) {
|
||||
@@ -253,30 +259,31 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(annotation);
|
||||
if (attributes.isEmpty() && qualifier == null) {
|
||||
// if no attributes, the qualifier must be present
|
||||
// If no attributes, the qualifier must be present
|
||||
return false;
|
||||
}
|
||||
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
|
||||
String attributeName = entry.getKey();
|
||||
Object expectedValue = entry.getValue();
|
||||
Object actualValue = null;
|
||||
// check qualifier first
|
||||
// Check qualifier first
|
||||
if (qualifier != null) {
|
||||
actualValue = qualifier.getAttribute(attributeName);
|
||||
}
|
||||
if (actualValue == null) {
|
||||
// fall back on bean definition attribute
|
||||
// Fall back on bean definition attribute
|
||||
actualValue = bd.getAttribute(attributeName);
|
||||
}
|
||||
if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
|
||||
expectedValue instanceof String && bdHolder.matchesName((String) expectedValue)) {
|
||||
// fall back on bean name (or alias) match
|
||||
// Fall back on bean name (or alias) match
|
||||
continue;
|
||||
}
|
||||
if (actualValue == null && qualifier != null) {
|
||||
// fall back on default, but only if the qualifier is present
|
||||
// Fall back on default, but only if the qualifier is present
|
||||
actualValue = AnnotationUtils.getDefaultValue(annotation, attributeName);
|
||||
}
|
||||
if (actualValue != null) {
|
||||
@@ -289,6 +296,25 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan
|
||||
return true;
|
||||
}
|
||||
|
||||
protected RootBeanDefinition getResolvedDecoratedDefinition(RootBeanDefinition rbd) {
|
||||
BeanDefinitionHolder decDef = rbd.getDecoratedDefinition();
|
||||
if (decDef != null && this.beanFactory instanceof ConfigurableListableBeanFactory) {
|
||||
ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) this.beanFactory;
|
||||
if (clbf.containsBeanDefinition(decDef.getBeanName())) {
|
||||
BeanDefinition dbd = clbf.getMergedBeanDefinition(decDef.getBeanName());
|
||||
if (dbd instanceof RootBeanDefinition) {
|
||||
return (RootBeanDefinition) dbd;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Annotation getFactoryMethodAnnotation(RootBeanDefinition bd, Class<? extends Annotation> type) {
|
||||
Method resolvedFactoryMethod = bd.getResolvedFactoryMethod();
|
||||
return (resolvedFactoryMethod != null ? AnnotationUtils.getAnnotation(resolvedFactoryMethod, type) : null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether the given dependency carries a value annotation.
|
||||
|
||||
Reference in New Issue
Block a user