Fixed QualifierAnnotationAutowireCandidateResolver's detection of custom qualifier annotations
Issue: SPR-10107
This commit is contained in:
parent
047db8cdf8
commit
c242abada1
|
@ -36,6 +36,7 @@ import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link AutowireCandidateResolver} implementation that matches bean definition qualifiers
|
* {@link AutowireCandidateResolver} implementation that matches bean definition qualifiers
|
||||||
|
@ -192,7 +193,7 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan
|
||||||
foundMeta = true;
|
foundMeta = true;
|
||||||
// Only accept fallback match if @Qualifier annotation has a value...
|
// Only accept fallback match if @Qualifier annotation has a value...
|
||||||
// Otherwise it is just a marker for a custom qualifier annotation.
|
// Otherwise it is just a marker for a custom qualifier annotation.
|
||||||
if ((fallbackToMeta && AnnotationUtils.getValue(metaAnn) == null) ||
|
if ((fallbackToMeta && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
|
||||||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
|
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@ public class QualifierAnnotationAutowireContextTests {
|
||||||
RootBeanDefinition person = new RootBeanDefinition(QualifiedPerson.class, cavs, null);
|
RootBeanDefinition person = new RootBeanDefinition(QualifiedPerson.class, cavs, null);
|
||||||
ConstructorArgumentValues cavs2 = new ConstructorArgumentValues();
|
ConstructorArgumentValues cavs2 = new ConstructorArgumentValues();
|
||||||
cavs2.addGenericArgumentValue(MARK);
|
cavs2.addGenericArgumentValue(MARK);
|
||||||
RootBeanDefinition person2 = new RootBeanDefinition(Person.class, cavs2, null);
|
RootBeanDefinition person2 = new RootBeanDefinition(DefaultValueQualifiedPerson.class, cavs2, null);
|
||||||
context.registerBeanDefinition(JUERGEN, person);
|
context.registerBeanDefinition(JUERGEN, person);
|
||||||
context.registerBeanDefinition(MARK, person2);
|
context.registerBeanDefinition(MARK, person2);
|
||||||
context.registerBeanDefinition("autowired",
|
context.registerBeanDefinition("autowired",
|
||||||
|
@ -745,13 +745,25 @@ public class QualifierAnnotationAutowireContextTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@TestQualifierWithDefaultValue
|
||||||
|
private static class DefaultValueQualifiedPerson extends Person {
|
||||||
|
|
||||||
|
public DefaultValueQualifiedPerson() {
|
||||||
|
super(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultValueQualifiedPerson(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Qualifier
|
@Qualifier
|
||||||
public static @interface TestQualifier {
|
public static @interface TestQualifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Qualifier
|
@Qualifier
|
||||||
public static @interface TestQualifierWithDefaultValue {
|
public static @interface TestQualifierWithDefaultValue {
|
||||||
|
|
|
@ -69,6 +69,21 @@ public abstract class StringUtils {
|
||||||
// General convenience methods for working with Strings
|
// General convenience methods for working with Strings
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the given String is empty.
|
||||||
|
* <p>This method accepts any Object as an argument, comparing it to
|
||||||
|
* <code>null</code> and the empty String. As a consequence, this method
|
||||||
|
* will never return <code>true</code> for a non-null non-String object.
|
||||||
|
* <p>The Object signature is useful for general attribute handling code
|
||||||
|
* that commonly deals with Strings but generally has to iterate over
|
||||||
|
* Objects since attributes may e.g. be primitive value objects as well.
|
||||||
|
* @param str the candidate String
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Object str) {
|
||||||
|
return (str == null || "".equals(str));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that the given CharSequence is neither <code>null</code> nor of length 0.
|
* Check that the given CharSequence is neither <code>null</code> nor of length 0.
|
||||||
* Note: Will return <code>true</code> for a CharSequence that purely consists of whitespace.
|
* Note: Will return <code>true</code> for a CharSequence that purely consists of whitespace.
|
||||||
|
|
Loading…
Reference in New Issue