diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/BeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/BeanFactory.java index d3d7552daca..6d641e9a26e 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/BeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/BeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -241,7 +241,7 @@ public interface BeanFactory { * @see #getBean * @see #isTypeMatch */ - Class getType(String name) throws NoSuchBeanDefinitionException; + Class getType(String name) throws NoSuchBeanDefinitionException; /** * Return the aliases for the given bean name, if any. diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java index 91265957f62..72068cdb156 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java @@ -24,6 +24,8 @@ import java.util.Set; 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.BeanDefinitionHolder; import org.springframework.beans.factory.config.DependencyDescriptor; import org.springframework.beans.factory.support.AutowireCandidateQualifier; @@ -47,12 +49,14 @@ import org.springframework.util.ObjectUtils; * @see Qualifier * @see Value */ -public class QualifierAnnotationAutowireCandidateResolver implements AutowireCandidateResolver { +public class QualifierAnnotationAutowireCandidateResolver implements AutowireCandidateResolver, BeanFactoryAware { private final Set> qualifierTypes; private Class valueAnnotationType = Value.class; + private BeanFactory beanFactory; + /** * Create a new QualifierAnnotationAutowireCandidateResolver @@ -112,11 +116,15 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan this.valueAnnotationType = valueAnnotationType; } + public void setBeanFactory(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + /** * Determine whether the provided bean definition is an autowire candidate. *

To be considered a candidate the bean's autowire-candidate - * attribute must not have been set to 'false'. Also if an annotation on + * attribute must not have been set to 'false'. Also, if an annotation on * the field or parameter to be autowired is recognized by this bean factory * as a qualifier, the bean must 'match' against the annotation as * well as any attributes it may contain. The bean definition must contain @@ -195,10 +203,18 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan if (bd.getResolvedFactoryMethod() != null) { targetAnnotation = bd.getResolvedFactoryMethod().getAnnotation(type); } - if (targetAnnotation == null && bd.hasBeanClass()) { + if (targetAnnotation == null) { // look for matching annotation on the target class - Class beanClass = bd.getBeanClass(); - targetAnnotation = beanClass.getAnnotation(type); + Class beanType = null; + if (this.beanFactory != null) { + beanType = this.beanFactory.getType(bdHolder.getBeanName()); + } + else if (bd.hasBeanClass()) { + beanType = bd.getBeanClass(); + } + if (beanType != null) { + targetAnnotation = ClassUtils.getUserClass(beanType).getAnnotation(type); + } } if (targetAnnotation != null && targetAnnotation.equals(annotation)) { return true; diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index ec8fd2c7aee..55801c8ad85 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -473,7 +473,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp } } - public Class getType(String name) throws NoSuchBeanDefinitionException { + public Class getType(String name) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); // Check manually registered singletons. diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java index 21f914a75a0..3095ee42716 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java @@ -181,7 +181,7 @@ class BeanDefinitionValueResolver { TypedStringValue typedStringValue = (TypedStringValue) value; Object valueObject = evaluate(typedStringValue.getValue()); try { - Class resolvedTargetType = resolveTargetType(typedStringValue); + Class resolvedTargetType = resolveTargetType(typedStringValue); if (resolvedTargetType != null) { return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType); } @@ -222,7 +222,7 @@ class BeanDefinitionValueResolver { * @throws ClassNotFoundException if the specified type cannot be resolved * @see TypedStringValue#resolveTargetType */ - protected Class resolveTargetType(TypedStringValue value) throws ClassNotFoundException { + protected Class resolveTargetType(TypedStringValue value) throws ClassNotFoundException { if (value.hasTargetType()) { return value.getTargetType(); } diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index a3eda4c784f..fc1d65322d2 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -37,6 +37,7 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCurrentlyInCreationException; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.CannotLoadBeanClassException; import org.springframework.beans.factory.FactoryBean; @@ -180,6 +181,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto */ public void setAutowireCandidateResolver(AutowireCandidateResolver autowireCandidateResolver) { Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null"); + if (autowireCandidateResolver instanceof BeanFactoryAware) { + ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this); + } this.autowireCandidateResolver = autowireCandidateResolver; } @@ -414,16 +418,19 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto beanName = BeanFactoryUtils.transformedBeanName(beanName); } - if (!containsBeanDefinition(beanName)) { - if (containsSingleton(beanName)) { - return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor); - } - else if (getParentBeanFactory() instanceof ConfigurableListableBeanFactory) { - // No bean definition found in this factory -> delegate to parent. - return ((ConfigurableListableBeanFactory) getParentBeanFactory()).isAutowireCandidate(beanName, descriptor); - } + if (containsBeanDefinition(beanName)) { + return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanName), descriptor); + } + else if (containsSingleton(beanName)) { + return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor); + } + else if (getParentBeanFactory() instanceof ConfigurableListableBeanFactory) { + // No bean definition found in this factory -> delegate to parent. + return ((ConfigurableListableBeanFactory) getParentBeanFactory()).isAutowireCandidate(beanName, descriptor); + } + else { + return true; } - return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanName), descriptor); } /** diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java index 7fdeeb029e6..fd0a1dfea0c 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +58,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } - return BeanUtils.instantiateClass(constructorToUse, null); + return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass. diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java index c715b127d43..68ec1cba6ac 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java @@ -143,7 +143,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory { return (targetType == null || (type != null && targetType.isAssignableFrom(type))); } - public Class getType(String name) throws NoSuchBeanDefinitionException { + public Class getType(String name) throws NoSuchBeanDefinitionException { String beanName = BeanFactoryUtils.transformedBeanName(name); Object bean = this.beans.get(beanName); diff --git a/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index d1deba73686..53ac5b1e5b3 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -898,7 +898,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader return getBeanFactory().isTypeMatch(name, targetType); } - public Class getType(String name) throws NoSuchBeanDefinitionException { + public Class getType(String name) throws NoSuchBeanDefinitionException { return getBeanFactory().getType(name); } diff --git a/org.springframework.context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java b/org.springframework.context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java index e21081c028a..a016839a949 100644 --- a/org.springframework.context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java +++ b/org.springframework.context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; - import javax.naming.NameNotFoundException; import javax.naming.NamingException; @@ -153,7 +152,7 @@ public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFac return (targetType == null || (type != null && targetType.isAssignableFrom(type))); } - public Class getType(String name) throws NoSuchBeanDefinitionException { + public Class getType(String name) throws NoSuchBeanDefinitionException { try { return doGetType(name); } diff --git a/org.springframework.context/src/test/java/org/springframework/aop/config/MethodLocatingFactoryBeanTests.java b/org.springframework.context/src/test/java/org/springframework/aop/config/MethodLocatingFactoryBeanTests.java index 43f5b36630b..2a469823c93 100644 --- a/org.springframework.context/src/test/java/org/springframework/aop/config/MethodLocatingFactoryBeanTests.java +++ b/org.springframework.context/src/test/java/org/springframework/aop/config/MethodLocatingFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 the original author or authors. + * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,14 @@ package org.springframework.aop.config; -import static org.easymock.EasyMock.*; -import static org.junit.Assert.*; - import java.lang.reflect.Method; +import static org.easymock.EasyMock.*; import org.junit.After; +import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; + import org.springframework.beans.factory.BeanFactory; /** @@ -107,7 +107,7 @@ public final class MethodLocatingFactoryBeanTests { @Test public void testSunnyDayPath() throws Exception { - expect(beanFactory.getType(BEAN_NAME)).andReturn(String.class); + expect((Class) beanFactory.getType(BEAN_NAME)).andReturn(String.class); replay(beanFactory); factory.setTargetBeanName(BEAN_NAME); @@ -117,12 +117,12 @@ public final class MethodLocatingFactoryBeanTests { assertNotNull(result); assertTrue(result instanceof Method); Method method = (Method) result; - assertEquals("Bingo", method.invoke("Bingo", new Object[]{})); + assertEquals("Bingo", method.invoke("Bingo")); } @Test(expected=IllegalArgumentException.class) public void testWhereMethodCannotBeResolved() { - expect(beanFactory.getType(BEAN_NAME)).andReturn(String.class); + expect((Class) beanFactory.getType(BEAN_NAME)).andReturn(String.class); replay(beanFactory); factory.setTargetBeanName(BEAN_NAME); diff --git a/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java b/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java index 249eb03d659..390489de125 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java +++ b/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java @@ -368,7 +368,7 @@ public abstract class ClassUtils { * @param clazz the class to check * @return the user-defined class */ - public static Class getUserClass(Class clazz) { + public static Class getUserClass(Class clazz) { return (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR) ? clazz.getSuperclass() : clazz); }