JAVA 动态加载
2008-11-04 17:18
309 查看
package dynamicClassLoader;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.util.Hashtable;
public class MyClassLoader extends ClassLoader {
// 定义哈希表(Hashtable)类型的变量,用于保存被载入的类数据。
Hashtable loadedClasses;
public MyClassLoader() {
loadedClasses = new Hashtable();
}
public synchronized Class loadClass(String className, boolean resolve)
throws ClassNotFoundException {
Class newClass;
byte[] classData;
// 检查要载入的类数据是否已经被保存在哈希表中。
newClass = (Class) loadedClasses.get(className);
// 如果类数据已经存在且resolve值为true,则解析它。
if (newClass != null) {
if (resolve)
resolveClass(newClass);
System.out.println(className + " is exist!");
return newClass;
}
// 先用(系统)父亲的classloader来加载,当在当前classpath下找不到该类字节码,则用自定义classLoader
try {
newClass = findSystemClass(className);
return newClass;
} catch (ClassNotFoundException e) {
System.out.println(className + " is not a system class!");
}
// 如果不是系统类,试图从网络中指定的URL地址载入类。
try {
// 用自定义方法载入类数据,存放于字节数组classData中。
classData = getClassData(className);
// 由字节数组所包含的数据建立一个class类型的对象。
newClass = defineClass(classData, 0, classData.length);
if (newClass == null)
throw new ClassNotFoundException(className);
} catch (Exception e) {
throw new ClassNotFoundException(className);
}
// 如果类被正确载入,则将类数据保存在哈希表中,以备再次使用。
loadedClasses.put(className, newClass);
// 如果resolve值为true,则解析类数据。
if (resolve) {
resolveClass(newClass);
}
return newClass;
}
protected byte[] getClassData(String className) throws Exception {
InputStream inputStream = null;
byte[] data = null;
if (true) {
data = this.getDataFromFile(className);
} else {
data = this.getDataFromURL(className);
}
return data;
}
// 这个方法从网络中载入类数据。
private byte[] getDataFromURL(String urlClassName) throws IOException {
byte[] data;
int length;
try {
// 从网络中采用URL类的方法, 载入指定URL地址的类的数据。
URL url = new URL(urlClassName.endsWith(".class") ? urlClassName
: urlClassName + ".class");
URLConnection connection = url.openConnection();
InputStream inputStream = connection.getInputStream();
length = connection.getContentLength();
data = new byte[length];
inputStream.read(data);
inputStream.close();
return data;
} catch (Exception e) {
throw new IOException(urlClassName);
}
}
private byte[] getDataFromFile(String className) throws IOException {
byte[] data;
File file = new File(className);
InputStream inputStream = new BufferedInputStream(new FileInputStream(
className));
int length = (int) file.length();
data = new byte[length];
inputStream.read(data);
inputStream.close();
return data;
}
public static void main(String[] args) throws Exception {
MyClassLoader mcl = new MyClassLoader();
Class test = mcl.loadClass("D://Test.class",true);//把编译好的 Test.class,复制到d:下
Constructor constructor = test.getConstructor(new Class[0]);
Object object = constructor.newInstance(new Class[0]);
Method method = test.getDeclaredMethod("printTest",new Class[0]);
method.invoke( object,new Object[0]);
}
}
------------------以下是 Test.java--------------
package dynamicClassLoader;
public class Test {
public Test(){
System.out.println("in constructor");
}
public void printTest () {
System.out.println("in print method");
}
}
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.util.Hashtable;
public class MyClassLoader extends ClassLoader {
// 定义哈希表(Hashtable)类型的变量,用于保存被载入的类数据。
Hashtable loadedClasses;
public MyClassLoader() {
loadedClasses = new Hashtable();
}
public synchronized Class loadClass(String className, boolean resolve)
throws ClassNotFoundException {
Class newClass;
byte[] classData;
// 检查要载入的类数据是否已经被保存在哈希表中。
newClass = (Class) loadedClasses.get(className);
// 如果类数据已经存在且resolve值为true,则解析它。
if (newClass != null) {
if (resolve)
resolveClass(newClass);
System.out.println(className + " is exist!");
return newClass;
}
// 先用(系统)父亲的classloader来加载,当在当前classpath下找不到该类字节码,则用自定义classLoader
try {
newClass = findSystemClass(className);
return newClass;
} catch (ClassNotFoundException e) {
System.out.println(className + " is not a system class!");
}
// 如果不是系统类,试图从网络中指定的URL地址载入类。
try {
// 用自定义方法载入类数据,存放于字节数组classData中。
classData = getClassData(className);
// 由字节数组所包含的数据建立一个class类型的对象。
newClass = defineClass(classData, 0, classData.length);
if (newClass == null)
throw new ClassNotFoundException(className);
} catch (Exception e) {
throw new ClassNotFoundException(className);
}
// 如果类被正确载入,则将类数据保存在哈希表中,以备再次使用。
loadedClasses.put(className, newClass);
// 如果resolve值为true,则解析类数据。
if (resolve) {
resolveClass(newClass);
}
return newClass;
}
protected byte[] getClassData(String className) throws Exception {
InputStream inputStream = null;
byte[] data = null;
if (true) {
data = this.getDataFromFile(className);
} else {
data = this.getDataFromURL(className);
}
return data;
}
// 这个方法从网络中载入类数据。
private byte[] getDataFromURL(String urlClassName) throws IOException {
byte[] data;
int length;
try {
// 从网络中采用URL类的方法, 载入指定URL地址的类的数据。
URL url = new URL(urlClassName.endsWith(".class") ? urlClassName
: urlClassName + ".class");
URLConnection connection = url.openConnection();
InputStream inputStream = connection.getInputStream();
length = connection.getContentLength();
data = new byte[length];
inputStream.read(data);
inputStream.close();
return data;
} catch (Exception e) {
throw new IOException(urlClassName);
}
}
private byte[] getDataFromFile(String className) throws IOException {
byte[] data;
File file = new File(className);
InputStream inputStream = new BufferedInputStream(new FileInputStream(
className));
int length = (int) file.length();
data = new byte[length];
inputStream.read(data);
inputStream.close();
return data;
}
public static void main(String[] args) throws Exception {
MyClassLoader mcl = new MyClassLoader();
Class test = mcl.loadClass("D://Test.class",true);//把编译好的 Test.class,复制到d:下
Constructor constructor = test.getConstructor(new Class[0]);
Object object = constructor.newInstance(new Class[0]);
Method method = test.getDeclaredMethod("printTest",new Class[0]);
method.invoke( object,new Object[0]);
}
}
------------------以下是 Test.java--------------
package dynamicClassLoader;
public class Test {
public Test(){
System.out.println("in constructor");
}
public void printTest () {
System.out.println("in print method");
}
}
相关文章推荐
- Java——反射(1.动态加载类)
- 黑马程序员————java中类的加载、反射、动态代理、枚举
- java动态加载jar,class
- java代码实现利用 classloader 动态加载 jar包、文件夹到classpath中
- 黑马程序员——【Java反射学习】动态加载类
- Java类动态加载(二)——动态加载class文件
- Java基础加强_Eclipse、枚举、反射、注解、泛型、类加载器、动态代理
- Java从Jar文件中动态加载类
- ECharts Java 动态加载数据,echartsjava
- java延迟加载和动态代理小结
- Java ClassLoader动态加载外部java代码
- java动态加载指定的类或者jar包反射调用其方法
- Java动态加载结合gradle的多模块构建
- java 使用类动态加载 实现模块化
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
- Java 静态加载类与动态加载类(初步认识Java的反射)
- Java 从Jar文件中动态加载类
- java学习Class动态加载
- JAVA动态加载JAR包的实现
- JAVA-SSM框架中配置mysql读写分离,动态加载数据源