当前位置:网站首页>Detailed explanation of contextclassloader
Detailed explanation of contextclassloader
2022-07-03 05:54:00 【Sloppy wandering swordsman】
ContextClassLoader It's through Thread.currentThread().getContextClassLoader() Returns the ClassLoader
1、 Pre knowledge
In the interpretation of the ContextClassLoader Before , Two knowledge points need to be mentioned first :
1) Parent delegation model

- Start class loader (Bootstrap ClassLoader): Responsible for placing
<JAVA HOME>\libIn the directory , Or be-XbootclasspathIn the path specified by the , And the class library identified by the virtual machine is loaded into the memory of the virtual machine . The boot class loader cannot be Java The program directly refers to , When you write a custom class loader , If you need to delegate the load request to the bootstrap loader , That's direct use null Instead of just - Extend the classloader (ExtClassLoader): from
sun.misc.Launcher$ExtClassLoaderRealization , It's responsible for loading<JAVA HOME>\lib\extIn the directory , Or bejava.ext.dirsAll class libraries in the path specified by the system variable , Developers can use the extension class loader directly - Application class loader (AppClassLoader): from
sun.misc.Launcher$AppClassLoaderRealization . Because this class loader is ClassLoader MediumgetSystemClassLoader()Return value of method , So it is generally called system class loading . It is responsible for loading the user classpath (ClassPath) All specified class libraries on , Developers can use this classloader directly , If there is no custom classloader in the application , In general, this is the default classloader in the program
This hierarchical relationship between class loading , Called a classloader Parent delegation model . The parental delegation model requires that in addition to the top-level boot loader , The rest of the class loaders should have their own parent class loaders . In this case, the parent-child relationship between class loaders will not be implemented by inheritance relationship , Instead, they all use composition relationships to reuse the code of the parent loader
How the parent delegation model works : If a class loader receives a class load request , It doesn't try to load the class itself first , Instead, delegate the request to the parent loader to complete , This is true of class loaders at every level , Therefore, all load requests should eventually be sent to the top-level startup class loader , Only when the parent loader feeds back that it cannot complete the load request ( It did not find the required class in its search scope ) when , Sub loader will try to load by itself
Use the parental delegation model to organize the relationships between class loaders , One obvious advantage is Java Class has a hierarchical relationship with priority along with its classloader . For example, class java.lang.Object, It's stored in rt.jar In , No matter which class loader wants to load this class , Finally, it is delegated to the startup class loader at the top of the model for loading , therefore Object Class is the same class in all kinds of classloader environments of the program
2) If a class is supported by a class loader A load , Then the dependent classes of this class are also loaded by the same class loader
such as Spring As a Bean factory , It needs to create an instance of the business class , And you need to load these classes before creating business class instances .Spring By calling Class.forName To load the business class . call Class.forName() When , Will get the class loader of the class that calls the method , Use this class loader to load Class.forName() Class passed in from , The code is as follows :
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement {
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
// Get the class that calls the method
Class<?> caller = Reflection.getCallerClass();
// ClassLoader.getClassLoader Get the class loader of the class that calls the method
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
2、 Why ContextClassLoader?
When we need to load a class , From custom ClassLoader, To AppClassLoader, Until then ExtClassLoader, The last to Bootstrap ClassLoader. That's all right. , Very smoothly . This is loading from bottom to top . But the other way around , When loading from top to bottom , This becomes an impossible task . To make up for this defect , Specially designed ContextClassLoader
Here you may have a question : Why does it load from top to bottom . For example, a class is composed of Bootstrap ClassLoader load , This class refers to a class developed by ourselves ( This kind can be AppClassLoader Load but cannot be Bootstrap ClassLoader load ), from If a class is supported by a class loader A load , Then the dependent classes of this class are also loaded by the same class loader You know : By default, our own classes will be Bootstrap ClassLoader Try loading , Eventually, an exception will be thrown because it cannot be loaded into the class
With SPI For example ,SPI Interface belongs to Java Core library , from BootstrapClassLoader load , When SPI When the interface wants to reference the specific methods of the third-party implementation class ,BootstrapClassLoader Unable to load Classpath Third party implementation classes under , At this time, you need to use the thread context class loader ContextClassLoader To solve . With the help of this mechanism, we can break the restriction of parental entrustment mechanism
SPI Core class ServiceLoader Source code is as follows :
public final class ServiceLoader<S>
implements Iterable<S>
{
public static <S> ServiceLoader<S> load(Class<S> service) {
// Thread context class loader , stay Launcher The constructor of the class is assigned AppClassLoader, It can read ClassPath Custom classes under
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return ServiceLoader.load(service, cl);
}

3、ContextClassLoader The default is AppClassLoader
JVM Startup time , Going to call Launcher Construction method of class :
public class Launcher {
public Launcher() {
ClassLoader extcl;
try {
// First, create the extension class loader
extcl = ExtClassLoader.getExtClassLoader();
} catch (IOException e) {
throw new InternalError(
"Could not create extension class loader");
}
// Now create the class loader to use to launch the application
try {
// To create a AppClassLoader And put extcl Passed as parent loader to AppClassLoader
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
"Could not create application class loader");
}
// Set thread context class loader , Analyze later
Thread.currentThread().setContextClassLoader(loader);
// Omit other code ...
}
Launcher When initializing, you will first create ExtClassLoader Class loader , And then create AppClassLoader And put ExtClassLoader Pass it as the parent class loader , also hold AppClassLoader The default setting is thread context class loader
4、 Sub thread ContextClassLoader It defaults to the parent thread ContextClassLoader
Thread stay init() Methods will include sub threads ContextClassLoader Set as parent thread ContextClassLoader
public
class Thread implements Runnable {
private ClassLoader contextClassLoader;
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
// Omit other code ...
// The current thread is the parent thread
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */
/* If there is a security manager, ask the security manager what to do. */
if (security != null) {
g = security.getThreadGroup();
}
/* If the security doesn't have a strong opinion of the matter use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
}
/* checkAccess regardless of whether or not threadgroup is explicitly passed in. */
g.checkAccess();
/* * Do we have the required permissions? */
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
g.addUnstarted();
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
// Sub thread ContextClassLoader Set as parent thread ContextClassLoader
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
// Omit other code ...
}
Reference resources :
https://zhuanlan.zhihu.com/p/58793441
https://blog.csdn.net/a1240466196/article/details/105375410
边栏推荐
- [teacher Zhao Yuqiang] the most detailed introduction to PostgreSQL architecture in history
- JDBC connection database steps
- Why should there be a firewall? This time xiaowai has something to say!!!
- Personal outlook | looking forward to the future from Xiaobai's self analysis and future planning
- Deep learning, thinking from one dimensional input to multi-dimensional feature input
- [trivia of two-dimensional array application] | [simple version] [detailed steps + code]
- There is no one of the necessary magic skills PXE for old drivers to install!!!
- Using the ethtool command by example
- How to set up altaro offsite server for replication
- [set theory] relational closure (reflexive closure | symmetric closure | transitive closure)
猜你喜欢

【一起上水硕系列】Day 10

Understand the first prediction stage of yolov1

Qt读写Excel--QXlsx插入图表5

Apt update and apt upgrade commands - what is the difference?

Redhat7系统root用户密码破解

Understand expectations (mean / estimate) and variances

Notepad++ wrap by specified character

深度学习,从一维特性输入到多维特征输入引发的思考
![[teacher Zhao Yuqiang] index in mongodb (Part 1)](/img/2d/277ec737f2a7065831a19d036e61e1.jpg)
[teacher Zhao Yuqiang] index in mongodb (Part 1)

PHP notes are super detailed!!!
随机推荐
[trivia of two-dimensional array application] | [simple version] [detailed steps + code]
Mapbox tasting value cloud animation
It is said that the operation and maintenance of shell scripts are paid tens of thousands of yuan a month!!!
[teacher Zhao Yuqiang] kubernetes' probe
期末复习(DAY6)
Niuke JS separator
Final review (Day6)
NG Textarea-auto-resize
[set theory] relational closure (relational closure related theorem)
1. Sum of two numbers
"C and pointer" - Chapter 13 advanced pointer int * (* (* (*f) () [6]) ()
[escape character] [full of dry goods] super detailed explanation + code illustration!
[set theory] relational closure (reflexive closure | symmetric closure | transitive closure)
EMD distance - example of use
Linux登录MySQL出现ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
Analysis of the example of network subnet division in secondary vocational school
一起上水硕系列】Day 9
2022.7.2 simulation match
Notepad++ wrap by specified character
Why should there be a firewall? This time xiaowai has something to say!!!