public interface SmartClassLoader
If a ClassLoader does not implement this interface, then all the classes obtained from it should be considered as not reloadable (i.e. cacheable).
Modifier and Type | Method and Description |
---|---|
default ClassLoader |
getOriginalClassLoader()
Return the original ClassLoader for this SmartClassLoader, or potentially
the present loader itself if it is self-sufficient.
|
default boolean |
isClassReloadable(Class<?> clazz)
Determine whether the given class is reloadable (in this ClassLoader).
|
default Class<?> |
publicDefineClass(String name,
byte[] b,
ProtectionDomain protectionDomain)
Define a custom class (typically a CGLIB proxy class) in this class loader.
|
default boolean isClassReloadable(Class<?> clazz)
Typically used to check whether the result may be cached (for this
ClassLoader) or whether it should be reobtained every time.
The default implementation always returns false
.
clazz
- the class to check (usually loaded from this ClassLoader)Class
object) later ondefault ClassLoader getOriginalClassLoader()
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 return getParent();
).
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.
ClassLoader.getParent()
,
AbstractAutoProxyCreator
default Class<?> publicDefineClass(String name, byte[] b, @Nullable ProtectionDomain protectionDomain)
This is a public equivalent of the protected
defineClass(String, byte[], int, int, ProtectionDomain)
method
in ClassLoader
which is traditionally invoked via reflection.
A concrete implementation in a custom class loader should simply delegate
to that protected method in order to make classloader-specific definitions
publicly available without "illegal access" warnings on JDK 9+:
return defineClass(name, b, 0, b.length, protectionDomain)
.
Note that the JDK 9+ Lookup#defineClass
method does not support
a custom target class loader for the new definition; it rather always
defines the class in the same class loader as the lookup's context class.
name
- the name of the classb
- the bytes defining the classprotectionDomain
- the protection domain for the class, if anyLinkageError
- in case of a bad class definitionSecurityException
- in case of an invalid definition attemptUnsupportedOperationException
- in case of a custom definition attempt
not being possible (thrown by the default implementation in this interface)ClassLoader.defineClass(String, byte[], int, int, ProtectionDomain)