Allow AOP proxies to be created using the original ClassLoader
Closes gh-26601
This commit is contained in:
parent
8baf404893
commit
e53cce0778
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -46,6 +46,7 @@ import org.springframework.beans.factory.FactoryBean;
|
|||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.core.SmartClassLoader;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
@ -458,7 +459,11 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
|||
proxyFactory.setPreFiltered(true);
|
||||
}
|
||||
|
||||
return proxyFactory.getProxy(getProxyClassLoader());
|
||||
ClassLoader targetClassLoader = getProxyClassLoader();
|
||||
if (targetClassLoader instanceof SmartClassLoader && targetClassLoader != beanClass.getClassLoader()) {
|
||||
targetClassLoader = ((SmartClassLoader) targetClassLoader).getOriginalClassLoader();
|
||||
}
|
||||
return proxyFactory.getProxy(targetClassLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,6 +47,28 @@ public interface SmartClassLoader {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the original ClassLoader for this SmartClassLoader, or potentially
|
||||
* the present loader itself if it is self-sufficient.
|
||||
* <p>The default implementation returns the local ClassLoader reference as-is.
|
||||
* In case of a reloadable or other selectively overriding ClassLoader which
|
||||
* commonly deals with unaffected classes from a base application class loader,
|
||||
* this should get implemented to return the original ClassLoader that the
|
||||
* present loader got derived from (e.g. through {@code return getParent();}).
|
||||
* <p>This gets specifically used in Spring's AOP framework to determine the
|
||||
* class loader for a specific proxy in case the target class has not been
|
||||
* defined in the present class loader. In case of a reloadable class loader,
|
||||
* we prefer the base application class loader for proxying general classes
|
||||
* not defined in the reloadable class loader itself.
|
||||
* @return the original ClassLoader (the same reference by default)
|
||||
* @since 5.3.5
|
||||
* @see ClassLoader#getParent()
|
||||
* @see org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
|
||||
*/
|
||||
default ClassLoader getOriginalClassLoader() {
|
||||
return (ClassLoader) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a custom class (typically a CGLIB proxy class) in this class loader.
|
||||
* <p>This is a public equivalent of the protected
|
||||
|
|
Loading…
Reference in New Issue