当前位置:网站首页>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
边栏推荐
- Source insight License Activation
- Why should there be a firewall? This time xiaowai has something to say!!!
- Ansible firewall firewalld setting
- 期末复习(day3)
- Btrfs and ext4 - features, strengths and weaknesses
- Final review (Day2)
- Yum is too slow to bear? That's because you didn't do it
- redis 无法远程连接问题。
- 卷积神经网络CNN中的卷积操作详解
- Sorry, this user does not exist!
猜你喜欢

【一起上水硕系列】Day 10
![[teacher Zhao Yuqiang] redis's slow query log](/img/a7/2140744ebad9f1dc0a609254cc618e.jpg)
[teacher Zhao Yuqiang] redis's slow query log

Linux登录MySQL出现ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)

Bernoulli distribution, binomial distribution and Poisson distribution, and the relationship between maximum likelihood (incomplete)
![[Shangshui Shuo series together] day 10](/img/a3/e8b9df588bef67ead925813a75c8c0.png)
[Shangshui Shuo series together] day 10

Pytorch builds the simplest version of neural network

最大似然估计,散度,交叉熵
![[teacher Zhao Yuqiang] Flink's dataset operator](/img/cc/5509b62756dddc6e5d4facbc6a7c5f.jpg)
[teacher Zhao Yuqiang] Flink's dataset operator

Solve the problem of automatic disconnection of SecureCRT timeout connection
![[teacher Zhao Yuqiang] Cassandra foundation of NoSQL database](/img/cc/5509b62756dddc6e5d4facbc6a7c5f.jpg)
[teacher Zhao Yuqiang] Cassandra foundation of NoSQL database
随机推荐
Final review (Day5)
[teacher Zhao Yuqiang] redis's slow query log
Complete set of C language file operation functions (super detailed)
Yum is too slow to bear? That's because you didn't do it
MySQL 5.7.32-winx64 installation tutorial (support installing multiple MySQL services on one host)
1. Sum of two numbers
[untitled]
Notepad++ wrap by specified character
The server data is all gone! Thinking caused by a RAID5 crash
为什么网站打开速度慢?
Introduction to redis using Lua script
Altaro virtual machine replication failed: "unsupported file type vmgs"
Export the altaro event log to a text file
Loss function in pytorch multi classification
2022.7.2 simulation match
一起上水碩系列】Day 9
Communication - how to be a good listener?
Maximum likelihood estimation, divergence, cross entropy
[teacher Zhao Yuqiang] MySQL flashback
多线程与高并发(7)——从ReentrantLock到AQS源码(两万字大章,一篇理解AQS)