From the source of the JDK is actually URLClassLoader inherited ClassLoader, that is to say URLClassLoader ClassLoader extended a bit, so you can understand URLClassLoader function to more points. ClassLoader can only load classes below classpath, and URLClassLoader may load classes under any path. Their inheritance relationship is as follows:
public class URLClassLoader extends Secureclassloader {}
public class Secureclassloader extends ClassLoader {}
URLClassLoader is a class under the java.net package. General dynamic load classes are directly using the Class.forName () method, but this method can only create classes that have already been referenced in the program, and can only be indexed by the method of the package name. For example, Java.lang.String cannot create a. class file or a class in a. jar package that is not in the program reference.
URLClassLoader provides this feature, which allows us to load in several ways:
* File: (loaded from File system directory)
* Jar Package: (Loaded from the jar package)
* http: (loaded from the remote HTTP service)
When the class file or resources resource file is updated, we need to reload these classes or jars. Theoretically, when the application cleans up a reference to the loaded object, the garbage collector collects the objects, and then we reload the new jar file and create a new urlclassloader to load. But here's the problem: we don't know when the garbage collector will collect those unreferenced objects, especially in Windows, because files opened in Windows cannot be deleted or replaced.
In build version 48 of Java7, URLClassLoader provides a close () method that frees all open resources, which saves developers a lot of time to deal with this problem.
URL url = new URL ("File:foo.jar"); URLClassLoader loader = new URLClassLoader (new url[] {URL}); Class cl = class.forname ("Foo", true, loader); Runnable foo = (Runnable) cl.newinstance (); Foo.run (); Loader.close ();//Foo.jar gets updated Somehowloader = new URLClassLoader (new url[] {URL}); CL = Class.forName ("Foo", true, loader); Foo = (Runnable) cl.newinstance (); Run the new implementation of Foo Foo.run ();
"Instance 1 loads a class file on the disk"
1. Define an interface and implementation class:
Itest.java
Package classload;
Public interface ITest {
Public String getstr ();
}
Test.java
Package classload;
public class Test implements itest{
public static void Main (string[] args) {
}
Public String Getstr () {
System.out.println ("Ceshi ...");
return "Ceshi";
}
}
2. Using URLClassLoader:
Package classload;
Import Java.io.File;
Import Java.net.URL;
Import Java.net.URLClassLoader;
public class Urlclassloadertest {
public static void Main (string...strings) throws Exception {
File Xfile=new file ("F:\\apache-tomcat-6.0.43\\webapps\\root");
URL xurl= Xfile.tourl ();
URLClassLoader classloader=new URLClassLoader (new url[]{xurl});
Class Xclass=classloader.loadclass ("Classload.test");
SYSTEM.OUT.PRINTLN ("--------Loader:" +xclass.getclassloader ());
System.out.println ("======= Reflection Call Method");
Object xobject=xclass.newinstance ();
Xclass.getmethod ("Getstr"). Invoke (XObject);
System.out.println ("======= uses interface to receive loaded objects");
ITest test = (ITest) xclass.newinstance ();
Test.getstr ();
}
}
Output:
--------Loader: [Email protected]
======= Reflection Call Method
Ceshi ...
======= using interfaces to receive loaded objects
Ceshi ...
Note:
1) When testing the local Test.java to be deleted, otherwise, according to the parent delegation algorithm and the JVM to determine the same class instance method, will load the local test instance first, and no longer load the class instance under the F disk.
2) Copy the generated Test.class file to the F:\\apache-tomcat-6.0.43\\webapps\\root\\classload directory. Where Classload is the package structure.
3) When you run the LoadClass method, the parameter uses the full-name of the class, and the URL does not include the entry in the path.
"Instance 2 loads a class in the Jar"
1. Package Itest.java and Test.java into jar files
2. Test method:
public static void Load2 () throws exception{
URL urls[] = new URL[1];
Urls[0] = new URL ("File:d:/test_fat.jar");
URLClassLoader classloader=new URLClassLoader (URLs);
Class Xclass=classloader.loadclass ("Classload.test");
SYSTEM.OUT.PRINTLN ("--------Loader 1:" +xclass.getclassloader ());
System.out.println ("======= Reflection Call Method 1");
Object xobject=xclass.newinstance ();
Xclass.getmethod ("Getstr"). Invoke (XObject);
System.out.println ("======= uses interface to receive loaded Object 1");
ITest test = (ITest) xclass.newinstance ();
Test.getstr ();
}
Output:
--------Loader 1:java.net.ur[email protected]
======= Reflection Call Method 1
Ceshi ...
======= using interfaces to receive loaded objects 1
Ceshi ...
"Instance 3 deploys the above method to the Web server, throws an exception, and requires the use of the thread context ClassLoader"
URLClassLoader loader = new URLClassLoader (URLs);
If you are using a Web app, you need to use the following construction method
URLClassLoader loader = new URLClassLoader (URLs, Thread.CurrentThread (). Getcontextclassloader ());
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
URLClassLoader class Loader