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 e6909de3f6..4946a7f3a0 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 @@ -534,12 +534,24 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp } RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); + + // Check decorated bean definition, if any: We assume it'll be easier + // to determine the decorated bean's type than the proxy's type. + BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); + if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) { + RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd); + Class targetClass = predictBeanType(dbd.getBeanName(), tbd); + if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) { + return targetClass; + } + } + Class beanClass = predictBeanType(beanName, mbd); // Check bean class whether we're dealing with a FactoryBean. if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) { if (!BeanFactoryUtils.isFactoryDereference(name)) { - // If it's a FactoryBean, we want to look at what it creates, not the factory class. + // If it's a FactoryBean, we want to look at what it creates, not at the factory class. return getTypeForFactoryBean(beanName, mbd); } else { diff --git a/org.springframework.context/src/test/java/org/springframework/beans/factory/xml/support/CustomNamespaceHandlerTests.java b/org.springframework.context/src/test/java/org/springframework/beans/factory/xml/support/CustomNamespaceHandlerTests.java index 7629f4dab1..f4ee8ec405 100644 --- a/org.springframework.context/src/test/java/org/springframework/beans/factory/xml/support/CustomNamespaceHandlerTests.java +++ b/org.springframework.context/src/test/java/org/springframework/beans/factory/xml/support/CustomNamespaceHandlerTests.java @@ -46,7 +46,6 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.BeanDefinitionDecorator; @@ -68,6 +67,7 @@ import org.springframework.core.io.Resource; * @author Rob Harrop * @author Rick Evans * @author Chris Beams + * @author Juergen Hoeller */ public class CustomNamespaceHandlerTests { @@ -120,6 +120,7 @@ public class CustomNamespaceHandlerTests { public void testProxyingDecoratorNoInstance() throws Exception { String[] beanNames = this.beanFactory.getBeanNamesForType(ApplicationListener.class); assertTrue(Arrays.asList(beanNames).contains("debuggingTestBeanNoInstance")); + assertEquals(ApplicationListener.class, this.beanFactory.getType("debuggingTestBeanNoInstance")); try { this.beanFactory.getBean("debuggingTestBeanNoInstance"); fail("Should have thrown BeanCreationException");