Skip to content

Commit e53cce0

Browse files
committed
Allow AOP proxies to be created using the original ClassLoader
Closes spring-projectsgh-26601
1 parent 8baf404 commit e53cce0

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -46,6 +46,7 @@
4646
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
4747
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
4848
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
49+
import org.springframework.core.SmartClassLoader;
4950
import org.springframework.lang.Nullable;
5051
import org.springframework.util.Assert;
5152
import org.springframework.util.StringUtils;
@@ -458,7 +459,11 @@ protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
458459
proxyFactory.setPreFiltered(true);
459460
}
460461

461-
return proxyFactory.getProxy(getProxyClassLoader());
462+
ClassLoader targetClassLoader = getProxyClassLoader();
463+
if (targetClassLoader instanceof SmartClassLoader && targetClassLoader != beanClass.getClassLoader()) {
464+
targetClassLoader = ((SmartClassLoader) targetClassLoader).getOriginalClassLoader();
465+
}
466+
return proxyFactory.getProxy(targetClassLoader);
462467
}
463468

464469
/**

spring-core/src/main/java/org/springframework/core/SmartClassLoader.java

+22
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,28 @@ default boolean isClassReloadable(Class<?> clazz) {
4747
return false;
4848
}
4949

50+
/**
51+
* Return the original ClassLoader for this SmartClassLoader, or potentially
52+
* the present loader itself if it is self-sufficient.
53+
* <p>The default implementation returns the local ClassLoader reference as-is.
54+
* In case of a reloadable or other selectively overriding ClassLoader which
55+
* commonly deals with unaffected classes from a base application class loader,
56+
* this should get implemented to return the original ClassLoader that the
57+
* present loader got derived from (e.g. through {@code return getParent();}).
58+
* <p>This gets specifically used in Spring's AOP framework to determine the
59+
* class loader for a specific proxy in case the target class has not been
60+
* defined in the present class loader. In case of a reloadable class loader,
61+
* we prefer the base application class loader for proxying general classes
62+
* not defined in the reloadable class loader itself.
63+
* @return the original ClassLoader (the same reference by default)
64+
* @since 5.3.5
65+
* @see ClassLoader#getParent()
66+
* @see org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
67+
*/
68+
default ClassLoader getOriginalClassLoader() {
69+
return (ClassLoader) this;
70+
}
71+
5072
/**
5173
* Define a custom class (typically a CGLIB proxy class) in this class loader.
5274
* <p>This is a public equivalent of the protected

0 commit comments

Comments
 (0)