System class Loader
The system loader may be familiar with the ears, but in order to complete the point, let's simply say the system's ClassLoader.
public class Test {public static void main (string[] args) {ClassLoader CL1 = Test.class.getClassLoader (). GetParent (). Getp Arent (); System.out.println (CL1); ClassLoader Cl2 = Test.class.getClassLoader (). GetParent (); System.out.println (Cl2); ClassLoader Cl3 = Test.class.getClassLoader (); System.out.println (Cl3);}}
The result of the printing is:
Null
[Email protected]
[Email protected]
This is actually the three classloader used in the JDK system, where null is bootstrap ClassLoader, because there is a C + + implementation, so null is printed here. Extclassloader is extension ClassLoader. Appclassloader is the app ClassLoader or the system ClassLoader. They are responsible for loading the classes under their respective specified locations:
1) Bootstrap ClassLoader
Responsible for loading all classes in Jre/lib/rt.jar in $java_home, implemented by C + +, not classloader subclasses
2) Extension ClassLoader
Some jar packages that are responsible for loading the extensions in the JAVA platform, including the jar packages in $java_home Jre/lib/*.jar or-djava.ext.dirs specified directories
3) App ClassLoader
Responsible for loading the jar package specified in the Classpath and the class in the directory
The relationship of these three classloader can be seen through code: the parent of the App ClassLoader is Extension classloader,extension ClassLoader's parent is bootstrap ClassLoader.
Delegation mechanism
The so-called delegation mechanism is that when a class is loaded, the APP ClassLoader delegates his parent (Extension ClassLoader) to load, Extension ClassLoader also entrusts his parent to load until bootstrap ClassLoader, if the parent does not load successfully, then it is loaded by itself.
Above three class loaders, in addition to Bootstrap ClassLoader are indirectly inherited from the ClassLoader class (is an abstract class can not be instantiated, but there is no abstract method), the implementation of the delegation mechanism is LoadClass method as a template method implementation. The following is through the LoadClass source analysis of the delegation mechanism:
Custom Class Loaders
Sometimes we may need to customize our ClassLoader to meet our special needs. And we generally do not need to destroy the delegation mechanism (the example of a class loader that destroys the delegation mechanism) can usually be implemented in two ways
First, inherit URLClassLoader, for example
public class Testclassloader extends URLClassLoader {public testclassloader (url[] URLs) {super (URLs);} Public Testclassloader (url[] Urls,classloader parent) {super (urls,parent);}}
You just need to call the parent constructor method, and you don't have to rewrite the other methods. This is also the simplest implementation. You only need to call LoadClass when you use it. The downside is that you can only locate the class you want to load via the URL.
Second, inherit the ClassLoader class and rewrite the Findclass method. Like what
public class Testclassloader extends ClassLoader {private String Basedir;public Testclassloader (String basedir,classloader parent) {super (parent); this.basedir = Basedir;} @Overrideprotected class<?> Findclass (String name) throws classnotfoundexception {class<?> cls = null; StringBuffer sb = new StringBuffer (basedir); String classname = Name.replace ('. ', File.separatorchar) + ". Class"; Sb.append (file.separator + classname); File CLASSF = new file (sb.tostring ()); if (!classf.exists ()) {throw new ClassNotFoundException (); } byte[] Raw = new byte[(int) classf.length ()];try {inputstream fin = new FileInputStream (CLASSF); Fin.read ( RAW); Fin.close ();} catch (Exception e) {e.printstacktrace ();} CLS = DefineClass (name,raw,0,raw.length); return CLS; }}
In the Findclass method, we can find the classes we want to load in any way, using the way we read the files. The LoadClass method is also called when used.
Thread Context class Loader
The thread context ClassLoader (contextual class loader) was introduced from the beginning of JDK 1.2. The java.lang.Thread method in the class getContextClassLoader() and the setContextClassLoader(ClassLoader cl) context ClassLoader used to get and set the thread. If not setContextClassLoader(ClassLoader cl) set by method, the thread inherits the context class loader of its parent thread. The context class loader for the initial thread that the Java application runs is the system ClassLoader. Code that runs in a thread can load classes and resources through such loaders.
javax.xml.parsers package. The implementation code for these SPI is likely to be contained in a jar package that is dependent on the Java application, which can be found through the classpath (CLASSPATH), such as the jar package contained in the apache xerces that implements the JAXP SPI. The code in the SPI interface often needs to load specific implementation classes. such as in JAXP; in the javax.xml.parsers.DocumentBuilderFactory class; newinstance () method is used to generate a new documentbuilderfactory instance. The real class of the instance here is inherited from javax.xml.parsers.DocumentBuilderFactory , provided by the implementation of the SPI. For example, in Apache Xerces, the implemented class is Org.apache.xerces.jaxp.DocumentBuilderFactoryImpl . The problem is that the SPI interface is part of the Java Core library and is loaded by the boot class loader, and the Java class implemented by the SPI is typically loaded by the System class loader. The boot ClassLoader is unable to find the SPI implementation class because it only loads the Java core library. It also cannot delegate to the system ClassLoader because it is the ancestor class loader of the system ClassLoader. In other words, the class loader's delegation mechanism does not solve this problem.