提交 c986a1ef 编写于 作者: J Juergen Hoeller

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

Issue: SPR-10335
上级 6a043e3e
...@@ -572,17 +572,22 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac ...@@ -572,17 +572,22 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
} }
@Override @Override
protected Class predictBeanType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) { protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) {
Class beanClass = (mbd.getFactoryMethodName() != null ? Class<?> targetType = mbd.getTargetType();
getTypeForFactoryMethod(beanName, mbd, typesToMatch) : if (targetType == null) {
resolveBeanClass(mbd, beanName, typesToMatch)); 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 // Apply SmartInstantiationAwareBeanPostProcessors to predict the
// eventual type after a before-instantiation shortcut. // eventual type after a before-instantiation shortcut.
if (beanClass != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; 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]) || if (predicted != null && (typesToMatch.length != 1 || !FactoryBean.class.equals(typesToMatch[0]) ||
FactoryBean.class.isAssignableFrom(predicted))) { FactoryBean.class.isAssignableFrom(predicted))) {
return predicted; return predicted;
...@@ -590,7 +595,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac ...@@ -590,7 +595,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
} }
} }
} }
return beanClass; return targetType;
} }
/** /**
...@@ -607,8 +612,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac ...@@ -607,8 +612,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @return the type for the bean if determinable, or {@code null} else * @return the type for the bean if determinable, or {@code null} else
* @see #createBean * @see #createBean
*/ */
protected Class getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) { protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
Class factoryClass; Class<?> factoryClass;
boolean isStatic = true; boolean isStatic = true;
String factoryBeanName = mbd.getFactoryBeanName(); String factoryBeanName = mbd.getFactoryBeanName();
......
/* /*
* 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -61,8 +61,12 @@ public class RootBeanDefinition extends AbstractBeanDefinition { ...@@ -61,8 +61,12 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
boolean allowCaching = true; boolean allowCaching = true;
private volatile Class<?> targetType;
boolean isFactoryMethodUnique = false; boolean isFactoryMethodUnique = false;
final Object constructorArgumentLock = new Object();
/** Package-visible field for caching the resolved constructor or factory method */ /** Package-visible field for caching the resolved constructor or factory method */
Object resolvedConstructorOrFactoryMethod; Object resolvedConstructorOrFactoryMethod;
...@@ -75,15 +79,13 @@ public class RootBeanDefinition extends AbstractBeanDefinition { ...@@ -75,15 +79,13 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
/** Package-visible field for caching partly prepared constructor arguments */ /** Package-visible field for caching partly prepared constructor arguments */
Object[] preparedConstructorArguments; Object[] preparedConstructorArguments;
final Object constructorArgumentLock = new Object(); final Object postProcessingLock = new Object();
/** Package-visible field that indicates a before-instantiation post-processor having kicked in */
volatile Boolean beforeInstantiationResolved;
/** Package-visible field that indicates MergedBeanDefinitionPostProcessor having been applied */ /** Package-visible field that indicates MergedBeanDefinitionPostProcessor having been applied */
boolean postProcessed = false; 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 { ...@@ -236,6 +238,8 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
if (original instanceof RootBeanDefinition) { if (original instanceof RootBeanDefinition) {
RootBeanDefinition originalRbd = (RootBeanDefinition) original; RootBeanDefinition originalRbd = (RootBeanDefinition) original;
this.decoratedDefinition = originalRbd.decoratedDefinition; this.decoratedDefinition = originalRbd.decoratedDefinition;
this.allowCaching = originalRbd.allowCaching;
this.targetType = originalRbd.targetType;
this.isFactoryMethodUnique = originalRbd.isFactoryMethodUnique; this.isFactoryMethodUnique = originalRbd.isFactoryMethodUnique;
} }
} }
...@@ -251,6 +255,21 @@ public class RootBeanDefinition extends AbstractBeanDefinition { ...@@ -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. * Specify a factory method name that refers to a non-overloaded method.
*/ */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册