Browse Source

Enforce use of ClassLoader.loadClass in case of temporary ClassLoader

Issue: SPR-17452
pull/2011/head
Juergen Hoeller 6 years ago
parent
commit
5cd525a2b0
  1. 32
      spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java

32
spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java

@ -1362,6 +1362,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp @@ -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 @@ -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 @@ -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 @@ -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);
}

Loading…
Cancel
Save