当前位置:网站首页>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
边栏推荐
- Mapbox tasting value cloud animation
- [teacher Zhao Yuqiang] calculate aggregation using MapReduce in mongodb
- Ext4 vs XFS -- which file system should you use
- [teacher Zhao Yuqiang] MySQL high availability architecture: MHA
- 今天很多 CTO 都是被幹掉的,因為他沒有成就業務
- Error 1045 (28000) occurs when Linux logs in MySQL: access denied for user 'root' @ 'localhost' (using password: yes)
- 期末复习DAY8
- 【无标题】
- C 语言文件操作函数大全 (超详细)
- Detailed explanation of iptables (1): iptables concept
猜你喜欢
![[teacher Zhao Yuqiang] the most detailed introduction to PostgreSQL architecture in history](/img/18/f91d3d21a39743231d01f2e4015ef8.jpg)
[teacher Zhao Yuqiang] the most detailed introduction to PostgreSQL architecture in history

Why is the website slow to open?

Altaro virtual machine replication failed: "unsupported file type vmgs"

Apache+php+mysql environment construction is super detailed!!!

Mapbox tasting value cloud animation

【一起上水硕系列】Day 10
![[explain in depth the creation and destruction of function stack frames] | detailed analysis + graphic analysis](/img/df/884313a69fb1e613aec3497800f7ba.jpg)
[explain in depth the creation and destruction of function stack frames] | detailed analysis + graphic analysis

一起上水碩系列】Day 9

Understand expectations (mean / estimate) and variances

"C and pointer" - Chapter 13 function pointer 1: callback function 2 (combined with template to simplify code)
随机推荐
Linux登录MySQL出现ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
[function explanation (Part 1)] | | knowledge sorting + code analysis + graphic interpretation
AtCoder Beginner Contest 258(A-D)
Communication - how to be a good listener?
Deep learning, thinking from one dimensional input to multi-dimensional feature input
2022.DAY592
一起上水碩系列】Day 9
"C and pointer" - Chapter 13 function pointer 1: callback function 2 (combined with template to simplify code)
70 shell script interview questions and answers
2022.6.30DAY591
[explain in depth the creation and destruction of function stack frames] | detailed analysis + graphic analysis
Personal outlook | looking forward to the future from Xiaobai's self analysis and future planning
[together Shangshui Shuo series] day 7 content +day8
CAD插件的安装和自动加载dll、arx
[written examination question analysis] | | get [sizeof and strlen] [pointer and array] graphic explanation + code analysis
Altaro requirements for starting from backup on Hyper-V
[teacher Zhao Yuqiang] calculate aggregation using MapReduce in mongodb
JS implements the problem of closing the current child window and refreshing the parent window
[teacher Zhao Yuqiang] kubernetes' probe
Beaucoup de CTO ont été tués aujourd'hui parce qu'il n'a pas fait d'affaires