Cache target type per bean definition and allow for specifying it in advance

Issue: SPR-10335
master
Juergen Hoeller 12 years ago
parent 6a043e3ea1
commit c986a1efc1
  1. 23
      spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
  2. 31
      spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java

@ -572,17 +572,22 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
@Override
protected Class predictBeanType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) {
Class beanClass = (mbd.getFactoryMethodName() != null ?
getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
resolveBeanClass(mbd, beanName, typesToMatch));
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) {
Class<?> targetType = mbd.getTargetType();
if (targetType == null) {
targetType = (mbd.getFactoryMethodName() != null ? getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
resolveBeanClass(mbd, beanName, typesToMatch));
if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {
mbd.setTargetType(targetType);
}
}
// Apply SmartInstantiationAwareBeanPostProcessors to predict the
// eventual type after a before-instantiation shortcut.
if (beanClass != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Class predicted = ibp.predictBeanType(beanClass, beanName);
Class predicted = ibp.predictBeanType(targetType, beanName);
if (predicted != null && (typesToMatch.length != 1 || !FactoryBean.class.equals(typesToMatch[0]) ||
FactoryBean.class.isAssignableFrom(predicted))) {
return predicted;
@ -590,7 +595,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
}
}
return beanClass;
return targetType;
}
/**
@ -607,8 +612,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @return the type for the bean if determinable, or {@code null} else
* @see #createBean
*/
protected Class getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
Class factoryClass;
protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
Class<?> factoryClass;
boolean isStatic = true;
String factoryBeanName = mbd.getFactoryBeanName();

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@ -61,8 +61,12 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
boolean allowCaching = true;
private volatile Class<?> targetType;
boolean isFactoryMethodUnique = false;
final Object constructorArgumentLock = new Object();
/** Package-visible field for caching the resolved constructor or factory method */
Object resolvedConstructorOrFactoryMethod;
@ -75,15 +79,13 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
/** Package-visible field for caching partly prepared constructor arguments */
Object[] preparedConstructorArguments;
final Object constructorArgumentLock = new Object();
/** Package-visible field that indicates a before-instantiation post-processor having kicked in */
volatile Boolean beforeInstantiationResolved;
final Object postProcessingLock = new Object();
/** Package-visible field that indicates MergedBeanDefinitionPostProcessor having been applied */
boolean postProcessed = false;
final Object postProcessingLock = new Object();
/** Package-visible field that indicates a before-instantiation post-processor having kicked in */
volatile Boolean beforeInstantiationResolved;
/**
@ -236,6 +238,8 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
if (original instanceof RootBeanDefinition) {
RootBeanDefinition originalRbd = (RootBeanDefinition) original;
this.decoratedDefinition = originalRbd.decoratedDefinition;
this.allowCaching = originalRbd.allowCaching;
this.targetType = originalRbd.targetType;
this.isFactoryMethodUnique = originalRbd.isFactoryMethodUnique;
}
}
@ -251,6 +255,21 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
/**
* Specify the target type of this bean definition, if known in advance.
*/
public void setTargetType(Class<?> targetType) {
this.targetType = targetType;
}
/**
* Return the target type of this bean definition, if known
* (either specified in advance or resolved on first instantiation).
*/
public Class<?> getTargetType() {
return this.targetType;
}
/**
* Specify a factory method name that refers to a non-overloaded method.
*/

Loading…
Cancel
Save