Enforce use of ClassLoader.loadClass in case of temporary ClassLoader
Issue: SPR-17452
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user