From b64f680f199108fc83ca7a80afefe0c95f7ba803 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 2 Sep 2014 22:10:09 +0200 Subject: [PATCH] AbstractAutowireCapableBeanFactory calls postProcessBeforeInstantiation with fully resolved target type Issue: SPR-12140 Issue: SPR-12142 --- .../AbstractAutowireCapableBeanFactory.java | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 2423b1230e..89a18be737 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -589,14 +589,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac @Override 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); - } - } + Class targetType = determineTargetType(beanName, mbd, typesToMatch); + // Apply SmartInstantiationAwareBeanPostProcessors to predict the // eventual type after a before-instantiation shortcut. if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { @@ -615,7 +609,27 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac } /** - * Determine the bean type for the given bean definition which is based on + * Determine the target type for the given bean definition. + * @param beanName the name of the bean (for error handling purposes) + * @param mbd the merged bean definition for the bean + * @param typesToMatch the types to match in case of internal type matching purposes + * (also signals that the returned {@code Class} will never be exposed to application code) + * @return the type for the bean if determinable, or {@code null} otherwise + */ + protected Class determineTargetType(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); + } + } + return targetType; + } + + /** + * Determine the target type for the given bean definition which is based on * a factory method. Only called if there is no singleton instance registered * for the target bean already. *

This implementation determines the type matching {@link #createBean}'s @@ -625,7 +639,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac * @param mbd the merged bean definition for the bean * @param typesToMatch the types to match in case of internal type matching purposes * (also signals that the returned {@code Class} will never be exposed to application code) - * @return the type for the bean if determinable, or {@code null} else + * @return the type for the bean if determinable, or {@code null} otherwise * @see #createBean */ protected Class getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class... typesToMatch) { @@ -927,10 +941,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. - if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { - bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName); - if (bean != null) { - bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); + if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { + Class targetType = determineTargetType(beanName, mbd); + if (targetType != null) { + bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); + if (bean != null) { + bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); + } } } mbd.beforeInstantiationResolved = (bean != null);