AbstractInterceptorDrivenBeanDefinitionDecorator exposes decorated BeanDefinition for early type checking in AbstractBeanFactory (SPR-7006)

This commit is contained in:
Juergen Hoeller
2010-03-30 15:40:47 +00:00
parent 16eb915c95
commit 282de41f06
5 changed files with 69 additions and 21 deletions

View File

@@ -57,6 +57,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.SmartFactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.BeanExpressionResolver;
import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -473,7 +474,20 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return parentBeanFactory.isTypeMatch(originalBeanName(name), targetType);
}
// Retrieve corresponding bean definition.
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) {
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
Class targetClass = predictBeanType(dbd.getBeanName(), tbd, FactoryBean.class, typeToMatch);
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
return typeToMatch.isAssignableFrom(targetClass);
}
}
Class beanClass = predictBeanType(beanName, mbd, FactoryBean.class, typeToMatch);
if (beanClass == null) {
return false;

View File

@@ -24,6 +24,7 @@ import java.util.Set;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.util.Assert;
@@ -53,6 +54,8 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
private final Set<String> externallyManagedDestroyMethods = Collections.synchronizedSet(new HashSet<String>());
private BeanDefinitionHolder decoratedDefinition;
boolean isFactoryMethodUnique;
/** Package-visible field for caching the resolved constructor or factory method */
@@ -75,7 +78,6 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
final Object postProcessingLock = new Object();
/**
* Create a new RootBeanDefinition, to be configured through its bean
* properties and configuration methods.
@@ -224,7 +226,9 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
RootBeanDefinition(BeanDefinition original) {
super(original);
if (original instanceof RootBeanDefinition) {
this.isFactoryMethodUnique = ((RootBeanDefinition) original).isFactoryMethodUnique;
RootBeanDefinition originalRbd = (RootBeanDefinition) original;
this.decoratedDefinition = originalRbd.decoratedDefinition;
this.isFactoryMethodUnique = originalRbd.isFactoryMethodUnique;
}
}
@@ -289,6 +293,14 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
return this.externallyManagedDestroyMethods.contains(destroyMethod);
}
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) {
this.decoratedDefinition = decoratedDefinition;
}
public BeanDefinitionHolder getDecoratedDefinition() {
return this.decoratedDefinition;
}
@Override
public RootBeanDefinition cloneBeanDefinition() {