Before writing this article deliberately read the next more than 10 years ago in some chapters of a book, "Deep Java Virtual Machine", the harvest is still very large, at least know that the class loader in the security play a vital role, no nonsense to say, to see what the class loader is.
We know that the Java program we write will eventually be compiled into a class file, which is a binary file that is designed to be very compact because it facilitates the transfer of class files in the network, laying the Java language in the distributed domain, and another advantage is cross-platform, This is called a compile-time run everywhere. When the JVM executes the class file, the first thing to do is to load it, and the class loader is basically going to load the class file. The class loading mechanism in the JVM is the parent delegation, do not know why call the parents, the strange name, let's call it, then what is the parent delegation? To explain this concept, first look at the three kinds of loaders that are provided by default in the JVM.
Start the ClassLoader, bootstrap this loader is provided by C + +, Java program is not available, this loader is also the ancestor of the loader, it does not have a father. Specifically, it loads the JDK core class library below Jre/lib, or it can be specified by the -xbootclasspath startup parameter, and it is worth mentioning that the loader loads only the jar of a particular name, such as Rt.jar, the illegal jar which does not load .
Extension class loader (Extension ClassLoader), the extension ClassLoader is implemented by the Java language itself and is responsible for loading the Java_home/lib/ext directory, or by java.ext.dirs all class libraries in the path specified by the system variable, we are able to use the loader directly, and it is the child of the bootstrap loader.
The Application class loader (application ClassLoader), also known as the System ClassLoader, always mentions the concept of classpath when you start learning Java, and yes, this loader is the class that loads the classpath we specify. It is the child of the Extender class loader. It is also written by a Java program, and we can extend it.
After introducing the default three kinds of loaders, the parent-delegated model is easy to understand, and in the initial version of the JDK, class loading was not the model, and this concept was formally jdk1.2. That is, when our system loader tries to load a class through LoadClass, it first passes the loaded action to the parent loader (if there is one), such a layer of delivery, if the final root loader is not loaded into the class, then returns, in turn, the subclass loads, if all the ClassLoader are not loaded , the classnotfoundexception error is reported. The reason for this model is that because of security, assuming that we ourselves define an implementation of the Java.lang.Integer class and specify the ClassLoader to load, imagine that if the JVM loads an integer class that is not provided by the JDK, but we write it ourselves, it will be very dangerous. But in a delegated way, the integer class we define ourselves will never get the chance to load.
Look at the parents to appoint source code:
Protected synchronized class<?> loadclass (String name, Boolean resolve) throws ClassNotFoundException {// First, check if the class has already been loaded//check that the class has not been loaded, here the name is the class's permission named Class C = Findloadedclass (name); if (c = = Nu LL) {//If it has not been loaded and has a parent loader, delegate to the parent loader to load the try {if (parent! = null) { c = parent.loadclass (name, false);} else {//If there is no father, then With bootstrap loading, it can be imagined that the method is ultimately a native method C = findbootstrapclassornull (name);} } catch (ClassNotFoundException e) { //ClassNotFoundException thrown if class not found //from the Non-null parent Class Loader }//The parent loader fails to load, it loads if (c = = null) { //If still not found, then invoke Findclass in order / /To find the class. c = findclass (name);} } Perform parse, link action if (resolve) { resolveclass (c);} return c; }
in fact, our own extension of the ClassLoader can discard this parent-delegated loading model, and sometimes it must be done, one of the characteristics of parental delegation is that the class loaded by the parent loader is visible to the loader, but the reverse is not true, and the parent loader typically loads the underlying API. So most of the situation is not a problem, but there are special cases, the need for the underlying API to invoke the user implementation of the class, such as Jndi or Jdbc,jndi code by the startup class loader to load, the purpose is to centralize resources management and lookup, Each vendor has its own implementation located under Classpath, where Jndi is going to invoke the API,In this case there is a general call service Provider interface referred to as SPI, then the problem comes, because the parent class loader cannot invoke the code loaded by the child loader, and we do have such a request now. To solve this problem, there is a concept of a thread-context loader in Java that can be used to set a loader, Thread.CurrentThread (). Setcontextclassloader () in a threaded context. If it is not set to inherit ClassLoader from the parent thread, if it is set to default to the App class loader, with this method, Jndi can get this classloader to load the SPI code, that is, to load the action of the subclass to request the reverse, The parent loader delegates to the subclass to load, thus realizing the visibility of the SPI code.
JVM class Loader