Related links
- CSDN_GroupiesM notes sorting
- [JVM principle] P1 bytecode file (Java Class)
- [JVM principle] P2 class loader [this article]
JVM virtual machine + execution engine + local method interface
summary
- Class loader: the virtual machine loads the class file into memory, and finally forms a Java type that can be directly used by the virtual machine.
- 2.1 BootStrap class loader: Java_ The core class library under home / lib and some other packages are loaded into memory. (the bottom layer is implemented in C + +)
- 2.2 Extension class loader: Java_ The home / lib / ext class library and some other packages are loaded into memory. (subclass of ClassLoader)
- 2.3 Application class loader: load the class library under the path of the current class and its referenced third-party class library into memory. (subclass of ClassLoader)
- 2.4 Thread Context class loader: it destroys the "parent delegation model" and solves the problem that the spi interface cannot find the implementation class through the system loading class.
- Custom class loader: the above three belong to the system class loader. The system ClassLoader will only load the class files in the specified directory. If you want to load your own class files, you need to customize a ClassLoader.
Class 2 loader
- Class loader: the virtual machine loads the class file into memory, and finally forms a Java type that can be directly used by the virtual machine.
- 2.1 BootStrap class loader: Java_ The core class library under home / lib and some other packages are loaded into memory. (the bottom layer is implemented in C + +)
- 2.2 Extension class loader: Java_ The home /lib/ext class library and some other packages are loaded into memory. (subclass of ClassLoader)
- 2.3 Application class loader: load the class library under the path of the current class and its referenced third-party class library into memory. (subclass of ClassLoader)
- 2.4 Thread Context class loader: it destroys the "parent delegation model" and solves the problem that the spi interface cannot find the implementation class through the system loading class.
- Custom class loader: the above three belong to the system class loader. The system ClassLoader will only load the class files in the specified directory. If you want to load your own class files, you need to customize a ClassLoader.
2.1 class loading process
-
Class loading: we all know that Java code will be compiled into a class file, which describes various information of the class. The class class needs to be loaded into the virtual machine to run and use.
-
Class loading mechanism: the virtual machine loads the class file into memory, verifies, converts, parses and initializes the data, and finally forms a Java type that can be directly used by the virtual machine.
-
Load source
- 1. Local disk
- 2. Downloaded from the Internet class file
- 3. war, loaded under jar class file
- 4. Read from a special database class file (rare)
- 5. Dynamically compile java source files into class files, typically dynamic agents, and generate class files through runtime
2.2 classification of system loader
- When the JVM starts, it will not load all class files at once (memory will explode), but dynamically load them as needed. Therefore, class loaders are divided into five types according to different functional scenarios.
2.2.1 BootStrap loader
- First, let's take a look at the classes loaded by the boot class loader, which is responsible for loading sun boot. class. path:
- Bootstrap class loader is a class loader implemented with local code. It belongs to a part of the virtual machine. It is written in C + +. You can't see the source code
- Responsible for Java_ The core class library under home / lib or the jar package specified by the - Xbootclasspath option and other class libraries recognized by the virtual machine are loaded into memory.
- Also called boot class loader
package com.groupies.base.JVM; import java.util.Arrays; import java.util.List; /** * @author GroupiesM * @date 2021/1/29 * Class loader classification: 1 Bootstrap class loader */ public class bootClassLoaderLoadingPath { public static void main(String[] args) { //Gets the directory where the boot column loader loads String bootStrapLoadingPath=System.getProperty("sun.boot.class.path"); //Convert the loaded directory into a collection List<String> bootLoadingPathList= Arrays.asList(bootStrapLoadingPath.split(";")); for (String bootPath:bootLoadingPathList){ /* Directory loaded by the startup class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\resources. jar Directory loaded by the startup class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\rt.jar Directory loaded by the startup class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\sunrsasign. jar Directory loaded by the startup class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\jsse. jar Directory loaded by the startup class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\jce. jar Directory loaded by the startup class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\charsets. jar Directory loaded by the startup class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\jfr. jar Directory loaded by the startup class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\classes */ System.out.println("Directory to start class loader loading:"+bootPath); } } }
- The Bootstrap class loader uses {JRE_HOME}/lib to load classes, but you can also use the parameter - Xbootclasspath or system variable sun boot. class. Path to the specified directory to load the class.
- Generally speaking, {JRE_HOME}/lib stores the system classes required for the normal operation of the JVM, as shown in the following table:
file name | describe |
---|---|
rt.jar | The class definitions of runtime and J2SE are all in this package |
charsets.jar | Character set support package |
jce.jar | Is a set of packages that provide the framework and Implementation for encryption, key generation and negotiation, and Message Authentication Code (MAC) algorithm |
jsse.jar | Secure socket expansion package Java ™ Secure Socket Extension |
classlist | This file indicates the list of classes that should be loaded by the boot class loader |
net.properties | JVM network configuration information |
- After the Bootstrap ClassLoader loads the system classes, the JVM memory will show the following pattern:
- Guide the class loader to load the class information into the method area and organize it in a specific way. For a specific class, there should be runtime constant pool, type information, field information, method information, reference of class loader, reference of corresponding class instance and other information in the method area.
- The reference of class loader is NULL because these classes are loaded by bootstrap classloader, which is implemented in C + + language
- For the reference of the corresponding Class instance, after loading the Class information into the method area, the Class loader will create an instance of the corresponding Class type and put it into the heap as the entry and entry point for developers to access the Class definition in the method area.
2.2.2 Extension class loader
- The Extension class loader is responsible for loading Java Ext.dirs, we also write a piece of code to load it:
- The Extension class loader is implemented by Sun's ExtClassLoader (sun.misc.Launcher$ExtClassLoader). Java class, inherited from URLClassLoader Extension class loader.
- Responsible for JAVA_HOME /lib/ext or by the system variable - DJava The class library in the location specified by ext.dir is loaded into memory.
package com.groupies.base.JVM; import java.util.Arrays; import java.util.List; /** * @author GroupiesM * @date 2021/1/29 * Class loader classification: 2 Bootstrap class loader */ public class extClassLoaderLoadingPath { public static void main(String[] args) { //Gets the directory where the boot column loader loads String bootStrapLoadingPath = System.getProperty("java.ext.dirs"); //Convert the loaded directory into a collection List<String> bootLoadingPathList = Arrays.asList(bootStrapLoadingPath.split(";")); for (String bootPath : bootLoadingPathList) { /* Expand the directory loaded by the class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext Expand the directory loaded by the class loader: C:\WINDOWS\Sun\Java\lib\ext */ System.out.println("Expand the directory loaded by the class loader:" + bootPath); } } }
2.2.3 Application class loader
- The Application class loader is responsible for loading Java class. path
- Be responsible for loading the class and jar package under classpath under the project directory. Java class, inherited from URLClassLoader system class loader.
- Also called system class loader
package com.groupies.base.JVM; import java.util.Arrays; import java.util.List; /** * @author GroupiesM * @date 2021/1/29 * Class loader classification: 3 Application class loader */ public class appClassLoaderLoadingPath { public static void main(String[] args) { //Gets the directory where the boot column loader loads String bootStrapLoadingPath=System.getProperty("java.class.path"); //Convert the loaded directory into a collection List<String> bootLoadingPathList= Arrays.asList(bootStrapLoadingPath.split(";")); for (String bootPath:bootLoadingPathList){ /* Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\charsets. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\deploy. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\access-bridge-64. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\cldrdata. jar Directory loaded by application class loader: d:\development\java\java_ HOME\jdk1. 8\jre\lib\ext\dnsns. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\jaccess. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\jfxrt. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\localedata. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\nashorn. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\sunec. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\sunjce_ provider. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\sunmscapi. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\sunpkcs11. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\ext\zipfs. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\javaws. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\jce. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\jfr. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\jfxswt. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\jsse. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\management-agent. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\plugin. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\resources. jar Directory loaded by application class loader: D: \ development \ Java \ Java_ HOME\jdk1. 8\jre\lib\rt.jar Directory loaded by application class loader: F:\bakup\JAVA_PRACTICE\base01\target\classes Directory loaded by application class loader: D: \ development \ Java \ maven \ maven_ repository\org\springframework\spring-test\4.1.3. RELEASE\spring-test-4.1.3. RELEASE. jar Directory loaded by application class loader: D: \ development \ Java \ maven \ maven_ repository\org\springframework\spring-core\4.1.3. RELEASE\spring-core-4.1.3. RELEASE. jar Directory loaded by application class loader: D: \ development \ Java \ maven \ maven_ repository\commons-logging\commons-logging\1.2\commons-logging-1.2. jar Directory loaded by application class loader: D: \ development \ Java \ maven \ maven_ repository\junit\junit\4.12\junit-4.12. jar Directory loaded by application class loader: D: \ development \ Java \ maven \ maven_ repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3. jar Directory loaded by application class loader: D: \ development \ Java \ IntelliJ idea 2020.3.1 \ lib \ idea_ rt.jar */ System.out.println("Directory loaded by application class loader:"+bootPath); } } }
2.2.4 Custom class loader
- Custom class loader, through Java The subclass of lang. ClassLoader loads the class by itself. The three classloaders provided by the system JVM will only load the class files in the specified directory. What if we need to load the class files outside the application in a certain case? For example, under the local D disk, or to load a class file on the network, in this case, you can customize a ClassLoader. And we can encrypt and decrypt class files according to our own needs.
- How to customize ClassLoader:
- Create a new class that inherits from Java Lang. classloader, override its findClass method.
- Converts a class bytecode array to an instance of class
- Just call the loadClass method
- An important method of class loading process loadClass: it is written in the JDK document that class is loaded through the specified fully qualified class name through the loadClass(String,boolean) method with the same name.
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
- The above is the method prototype. The general steps to implement this method are
- Execute findLoadedClass(String) to check whether the class has been loaded. If it has been loaded, load it directly. If not, proceed to the next step.
- Executes the loadClass method of the parent loader. If the parent loader is null, the jvm's built-in loader will replace it, that is, Bootstrap ClassLoader. This also explains that the parent of ExtClassLoader is null, but it still says that Bootstrap ClassLoader is its parent loader.
- If the upward delegate parent loader fails to load successfully, find it through findClass(String).
- If the class is found in the above steps and the parameter resolve is true, loadClass() will call the resolveClass(Class) method to generate the final class object. We can see this step from the source code.
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check whether it has been loaded Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { //The parent loader is not empty. Call the loadClass of the parent loader c = parent.loadClass(name, false); } else { //If the parent loader is empty, call Bootstrap Classloader c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); //If the parent loader is not found, call findclass c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { //Call resolveClass() resolveClass(c); } return c; } }
- The code explains parental delegation.
- In addition, it should be noted that if you want to write a subclass of classloader, that is, customize a classloader, it is recommended to override the findClass() method instead of directly rewriting the loadClass() method.
- Write a custom class loader below: specify the class loading path in the lib folder under disk D.
- Create a new test Class, the code is as follows:
package com.test; public class Test { public void say() { System.out.println("Hello MyClassLoader"); } }
-
In test Open the dos window in the directory where Java is located
-
Compile test Java, generating class bytecode file
-
Put it into the specified directory D:/lib/com/Test
-
Custom loading class MyClassLoader
- a. Inherit ClassLoader
- b. Override findClass() method
- c. calls the middle note (defineClass) method in findClass() method: we define the method of finding class in findClass() method, and then generate Class object through defineClass().
- Note: if the parent is not specified when a ClassLoader is created, its parent is AppClassLoader by default, because this can ensure that it can access the class file successfully loaded by the built-in loader of the system.
package com.groupies.base.JVM.CustomClassLoader; import java.io.*; /** * @author GroupiesM * @date 2021/2/1 * Custom class loader * Through Java The subclass of lang. ClassLoader loads the class by itself. The system's ClassLoader will only load the class files in the specified directory. If you want to load your own class files, you can customize a ClassLoader. And we can encrypt and decrypt class files according to our own needs. * * How to customize ClassLoader: * Create a new class that inherits from Java Lang. classloader, override its findClass method. * Converts a class bytecode array to an instance of class * Just call the loadClass method */ public class MyClassLoader extends ClassLoader { private String classpath; public MyClassLoader(String classpath) { this.classpath = classpath; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { try { byte[] classDate = getDate(name); if (classDate == null) { } else { //The defineClass method converts bytecode into a class return defineClass(name, classDate, 0, classDate.length); } } catch (IOException e) { e.printStackTrace(); } return super.findClass(name); } /** Returns the bytecode of the class */ private byte[] getDate(String className) throws IOException { InputStream in = null; ByteArrayOutputStream out = null; String path = classpath + File.separatorChar + className.replace('.', File.separatorChar) + ".class"; try { in = new FileInputStream(path); out = new ByteArrayOutputStream(); byte[] buffer = new byte[2048]; int len = 0; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } return out.toByteArray(); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { in.close(); out.close(); } return null; } }
- Test class TestMyClassLoader
- Now, if you call the say method of a Test object, it will output the string "Hello MyClassLoader". But now we put Test Class is placed outside all directories of the application project. We need to load it and then execute its methods.
package com.groupies.base.JVM.CustomClassLoader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author GroupiesM * @date 2021/2/1 */ public class TestMyClassLoader { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { //Load path of custom classloader MyClassLoader myClassLoader = new MyClassLoader("D:\\lib"); //Package name + class name Class c = myClassLoader.loadClass("com.test.Test"); if (c != null) { Object obj = c.newInstance(); Method method = c.getMethod("say", null); method.invoke(obj, null); //Output result: //Hello MyClassLoader //com.groupies.base.JVM.CustomClassLoader.MyClassLoader@5cad8086 System.out.println(c.getClassLoader().toString()); } } }
2.2.5 Thread Context class loader
-
summary
- Introduced from JDK 1.2. Java. The methods getContextClassLoader() and setContextClassLoader(ClassLoader cl) in lang. thread are used to obtain and set the context class loader of the thread.
- If it is not set through the setContextClassLoader(ClassLoader cl) method, the thread will inherit the Thread Context classloader of its parent thread.
- The Thread Context class loader of the initial thread of Java application running is the loader of system classes (including startup, extension, application and Thread Context classes). The code running in the thread can load classes and resources through this loader.
-
effect
- Thread context class loader fundamentally solves the problem that general applications cannot violate the parental delegation mode, making the Java class loading system more flexible. The problem mentioned above is the specialty of thread context class loader. If no settings are made, the thread context class loader of Java application is the system class loader by default. Therefore, using the thread context class loader in the SPI interface code can successfully load the classes implemented by SPI.
2.3 parent delegation mode
the so-called parental delegation model means that after a class receives a class loading request, it will pass the request to the parent class loader in turn (if any). If the parent class loader at the top level can be loaded, it will return successfully. If it cannot be loaded, it will be loaded to the child loader in turn.
the two parent delegation model ensures the stable operation of Java programs, avoids the repeated loading of classes, and ensures that the core API of Java is not tampered with.
- Let's take a look at the hierarchy of class loaders through the code:
- a. Application class loader AppClassLoader;
- b. The parent class is the extension class loader ExtClassLoader;
- c. The parent class of the extension class loader outputs a null;
- d. This null will call the BootStrap class loader. (according to the source code of ClassLoader class)
package com.groupies.base.JVM; /** * @author GroupiesM * @date 2021/1/29 * Classloader: parental delegation mechanism * Objective: write a class and output the class loader, parent class loader and parent class loader of this class in turn */ public class ClassLoaderPath { public static void main(String[] args) { //sun.misc.Launcher$AppClassLoader@18b4aac2 System.out.println(ClassLoaderPath.class.getClassLoader()); //sun.misc.Launcher$ExtClassLoader@2503dbd3 System.out.println(ClassLoaderPath.class.getClassLoader().getParent()); //null System.out.println(ClassLoaderPath.class.getClassLoader().getParent().getParent()); } }
-
ClassLoader class source code
-
Parental delegation model process
- When a class loader receives a class loading task, first check whether there is one in the cache. If not, delegate the task to its parent loader for execution.
- The parent loader does the same thing, delegating layer by layer up to the top-level BootStrap class loader.
- If the BootStrap class loader does not find the class to be loaded, it will return the loading task to the next level class loader for execution, and the next level class loader will do the same.
- If the lowest class loader still does not find the required class file, an exception is thrown.
-
Flow chart of parental delegation model
-
Why parent delegation
- Ensure the global uniqueness of the class and prevent the core API library from being tampered with at will.
- If you write a class with the same name as the class in the core class library, you will find that this class can be compiled normally, but it can never be loaded and run. Because any class is loaded for the first time, it will first be delegated to the top level, and the BootStrap class loader will look for it in the core class library. If there is no parent delegation mechanism to ensure the global uniqueness of the class, anyone can write a Java If the lang.Object class is placed under the classpath, the application will be in a mess.
- From the perspective of security, through the two parent delegation mechanism, the Java virtual machine always looks for the type from the most trusted Java core API (start class loader) first, which can prevent untrusted classes from posing as trusted classes and causing harm to the system.
The parental delegation model is not absolute. spi mechanism can break the parental delegation model.
2.4 destruction of parental delegation
- SPI(Service Provider Interface) mechanism
- SPI overview: SPI is a mechanism to find service implementation for interfaces: Java defines many interfaces in the core library and gives call logic for these interfaces, but does not give specific implementation. What developers need to do is customize an implementation class and register the implementation class information in META-INF/services for use by the core class library. The most typical is JDBC. After JDBC 4.0, we actually don't need to call class Forname to load the driver. We just need to put the jar package of the driver into the class loading path of the project, and the driver will be loaded automatically. This automatic loading technology is called SPI.
- Why does JDBC break the parental delegation model:
Java provides a Driver interface to drive the database connection of various manufacturers. The DriverManager class is located in Java_ The jre/lib/rt.jar package in home is loaded by the BootStrap class loader. According to the class loading mechanism, when the loaded class references another class, the virtual machine will load the first class, and the ClassLoader will load the referenced class. That is to say, to use the BootStrap class loader to load the implementation class of the Driver interface, we know that the BootStrap class loader is only responsible for loading Java by default_ All classes in jre/lib/rt.jar in home, so the Driver implementation needs to be loaded by the subclass loader, which destroys the parental delegation model.
check the source code of DriverManager class and see that its static code block will be triggered when using DriverManager. Call loadInitialDrivers() method and serviceloader Load (driver. Class) loads all data in meta-inf / services / Java sql. The classes in the driver file are transferred to the JVM memory to complete the automatic loading of the driver.
- So Java provides the spi mechanism. Even if the Driver is loaded by the bootstrap class loader, it can ask the Thread Context ClassLoader to request the subclass loader to complete the loading. The default is the Application class loader. But this does break the class loading mechanism.
- SPI overview: SPI is a mechanism to find service implementation for interfaces: Java defines many interfaces in the core library and gives call logic for these interfaces, but does not give specific implementation. What developers need to do is customize an implementation class and register the implementation class information in META-INF/services for use by the core class library. The most typical is JDBC. After JDBC 4.0, we actually don't need to call class Forname to load the driver. We just need to put the jar package of the driver into the class loading path of the project, and the driver will be loaded automatically. This automatic loading technology is called SPI.
2.5 SPI mechanism
- summary
- SPI (Service Provider Interface) mechanism: it is mainly used in vendor-defined components or plug-ins. In Java util. The API document of serviceloader is described in detail. SPI mechanism is an automatic loading technology that destroys the parental delegation model and is used to load the specific implementation classes of the interface.
- Idea of SPI mechanism: in object-oriented design, we generally recommend interface programming between modules, and there is no hard coding between modules. Once a specific implementation class is involved in the code, it violates the principle of pluggability. If you need to replace an implementation, you need to modify the code. In order to realize that the module assembly can not be dynamically specified in the program, a service discovery mechanism is needed. Java SPI provides such a mechanism: the mechanism to find service implementation for an interface. Similar to the idea of IOC, it is to move the control of assembly outside the program. This mechanism is particularly important in modular design.
- Example of SPI mechanism: after the service provider provides an implementation of the service interface, a file named after the service interface is created in the META-INF/services / directory of the jar package, which is the specific implementation class of the service interface. When the external program assembles this module, the specific implementation class name can be found through the configuration file in the jar package META-INF/services /, loaded and instantiated to complete the injection of the module. Based on such a convention, we can find the implementation class of the service interface without making it in the code. jdk provides a tool class for service implementation search: Java util. ServiceLoader. The implementation of JDBC SPI mysql is as follows.
- Problems of SPI mechanism:
Java provides many service SPIs, allowing third parties to provide implementations for these interfaces. The interfaces of these SPIs are provided by the Java core library, and the implementation of these SPIs is completed by various suppliers. The terminal only needs to include the required implementation into the CLASSPATH as a jar package that the Java application depends on. The problem is that the code in SPI interface often needs to load specific implementation classes: SPI interface is a part of Java core library and is loaded by BootStrap class loader; The implementation class of SPI is loaded by the system class loader. The startup class loader cannot find the implementation class of SPI (because it only loads the core library of Java). According to the parental delegation model, the startup class loader cannot delegate the system class loader to load classes. In other words, the parental delegation mode of class loader cannot solve this problem.
thread context class loader just solves this problem. The thread context class loader destroys the "parental delegation model", which can abandon the parental delegation loading chain mode in the execution thread, so that the program can use the class loader in reverse.
- SPI (Service Provider Interface) mechanism: it is mainly used in vendor-defined components or plug-ins. In Java util. The API document of serviceloader is described in detail. SPI mechanism is an automatic loading technology that destroys the parental delegation model and is used to load the specific implementation classes of the interface.
21/02/18
M