diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 390e6cbd549..d46b11437b6 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -1362,6 +1362,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp @Nullable protected Class resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class... typesToMatch) throws CannotLoadBeanClassException { + try { if (mbd.hasBeanClass()) { return mbd.getBeanClass(); @@ -1391,13 +1392,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp throws ClassNotFoundException { ClassLoader beanClassLoader = getBeanClassLoader(); - ClassLoader classLoaderToUse = beanClassLoader; + ClassLoader dynamicLoader = beanClassLoader; + boolean freshResolve = false; + if (!ObjectUtils.isEmpty(typesToMatch)) { // When just doing type checks (i.e. not creating an actual instance yet), // use the specified temporary class loader (e.g. in a weaving scenario). ClassLoader tempClassLoader = getTempClassLoader(); if (tempClassLoader != null) { - classLoaderToUse = tempClassLoader; + dynamicLoader = tempClassLoader; + freshResolve = true; if (tempClassLoader instanceof DecoratingClassLoader) { DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader; for (Class typeToMatch : typesToMatch) { @@ -1406,6 +1410,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp } } } + String className = mbd.getBeanClassName(); if (className != null) { Object evaluated = evaluateBeanDefinitionString(className, mbd); @@ -1415,18 +1420,31 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp return (Class) evaluated; } else if (evaluated instanceof String) { - return ClassUtils.forName((String) evaluated, classLoaderToUse); + className = (String) evaluated; + freshResolve = true; } else { throw new IllegalStateException("Invalid class name expression result: " + evaluated); } } - // When resolving against a temporary class loader, exit early in order - // to avoid storing the resolved Class in the bean definition. - if (classLoaderToUse != beanClassLoader) { - return ClassUtils.forName(className, classLoaderToUse); + if (freshResolve) { + // When resolving against a temporary class loader, exit early in order + // to avoid storing the resolved Class in the bean definition. + if (dynamicLoader != null) { + try { + return dynamicLoader.loadClass(className); + } + catch (ClassNotFoundException ex) { + if (logger.isTraceEnabled()) { + logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex); + } + } + } + return ClassUtils.forName(className, dynamicLoader); } } + + // Resolve regularly, caching the result in the BeanDefinition... return mbd.resolveBeanClass(beanClassLoader); }