Fixed QualifierAnnotationAutowireCandidateResolver's detection of custom qualifier annotations

Issue: SPR-10107
This commit is contained in:
Juergen Hoeller 2012-12-20 17:35:02 +01:00
parent 047db8cdf8
commit c242abada1
3 changed files with 31 additions and 3 deletions

View File

@ -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;
} }

View File

@ -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 {

View File

@ -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.