动态加载类及调用类函数
// ------------------------ DirClassLoader 类 --------------------
package com.cs.dynamic;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class DirClassLoader extends ClassLoader
{
/**
* 类加载器的核心代码 -加载类在需要的时候自动编译源文件。
* @param pkgDir 包所在路径,以“/”结束
* @param name 类名称,包括所在包名称,例如com.cs.worker.worker1
* @param resolve 是否解释类
* @throws ClassNotFoundException
* @return Class
*/
public Class loadClass(String pkgDir, String name, boolean resolve) throws ClassNotFoundException
{
//我们的目的是获得一个类对象。
Class clas = null;
// 首先,检查是否已经出理过这个类。
clas = findLoadedClass(name);
if(clas != null)
{
//System.out.println("finded Class: " + clas);
//return clas;
}
// 通过类名获得路径名比如:java.lang.Object => java/lang/Object
String fileStub = name.replace('.', '/');
// 构建指向类文件的对象。
String classFilename = pkgDir + fileStub + ".class";
File classFile = new File(classFilename);
if (classFile.exists())
// 我们开始加载原始字节。
try
{
// 读取字节。
byte raw[] = getBytes(classFilename);
// 转化为类对象
//System.out.println("load " + name + " from DirClassLoader");
clas = defineClass(name, raw, 0, raw.length);
}
catch (IOException ie)
{
// 这里并不表示失败,可能我们处理的类在本地类库中,如java.lang.Object。
}
//System.out.println( "defineClass: "+clas );
//可能在类库中,以默认的方式加载。
if (clas == null)
{
//System.out.println("load " + name + " from SysClassLoader");
clas = findSystemClass(name);
}
//System.out.println( "findSystemClass: "+clas );
// 如果参数resolve为true,根据需要解释类。
if (resolve && clas != null)
resolveClass(clas);
// 如果还没有获得类,说明出错了。
if (clas == null)
throw new ClassNotFoundException(name);
// 否则,返回这个类对象。
return clas;
}
/**
* 指定一个文件名,从磁盘读取整个文件内容,返回字节数组。
* @param filename String
* @throws IOException
* @return byte[]
*/
private byte[] getBytes(String filename) throws IOException
{
// 获得文件大小。
File file = new File(filename);
long len = file.length();
//创建一个数组刚好可以存放文件的内容。
byte raw[] = new byte[ (int) len];
// 打开文件
FileInputStream fin = new FileInputStream(file);
// 读取所有内容,如果没法读取,表示发生了一个错误。
int r = fin.read(raw);
if (r != len)
throw new IOException("Can′t read all, " + r + " != " + len);
// 别忘了关闭文件。
fin.close();
// 返回这个数组。
return raw;
}
}
// ------------------------ WorkerFactory ----------------------
package com.cs.dynamic;
public class WorkerFactory
{
@SuppressWarnings("unchecked")
public static Class getClassByName(String pkgDir, String className)
{
Class ret = null;
try
{
DirClassLoader dcl = new DirClassLoader();
ret = dcl.loadClass(pkgDir, className, false);
}
catch(Exception e)
{
e.printStackTrace();
}
return ret;
}
}
// ------------------------ WorkerManager --------------------------
package com.cs.dynamic;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class WorkerManager
{
@SuppressWarnings("unchecked")
public static Object invoke(Class clazz, String funcName, Params ps) throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
Object ret = null;
Class[] partypes = new Class[1];
partypes[0] = Params.class;
Method mth = clazz.getMethod(funcName, partypes);
Object arglist[] = new Object[1];
arglist[0] = ps;
Object methobj = clazz.newInstance();
ret = mth.invoke(methobj, arglist);
return ret;
}
}
// -------------------------- Params -------------------------------------
package com.cs.dynamic;
import java.util.ArrayList;
public class Params extends ArrayList<Param>
{
private static final long serialVersionUID = -2705421853334947899L;
public String getValueByName(String name)
{
String value = "";
if (name == null)
return value;
if ("".equals(name))
return value;
for (int n = 0; n < size(); n ++)
{
Param p = (Param)get(n);
if (name.equalsIgnoreCase(p.Name))
{
value = p.Value;
break;
}
}
return value;
}
}
// ------------------------ Param -----------------------------
package com.dynamic;
public class Param
{
public String Name = "";
public String Value = "";
}
// ---------------------- 测试 ------------------------------------
package com.cs.workers;
import com.cs.dynamic.Params;
public class Worker1
{
public String test(Params ps)
{
for (int n = 0; n < ps.size(); n ++)
System.out.println(ps.get(n).Name + "=" + ps.get(n).Value);
return "Hello!";
}
}
// ------------------- 测试代码 ---------------------------
import java.lang.reflect.InvocationTargetException;
import com.cs.dynamic.Param;
import com.cs.dynamic.Params;
import com.cs.dynamic.WorkerFactory;
import com.cs.dynamic.WorkerManager;
public class test {
/**
* @param args
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws IllegalArgumentException
* @throws SecurityException
*/
public static void main(String[] args) throws SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
{
// TODO Auto-generated method stub
//System.out.println(System.getProperty("user.dir"));
String dir = System.getProperty("user.dir") + "/bin/";
Class obj = WorkerFactory.getClassByName(dir, "com.cs.workers.Worker1");
Params ps = new Params();
Param p = new Param(); p.Name = "123"; p.Value = "dsa";
ps.add(p);
Object obj1 = WorkerManager.invoke(obj, "test", ps);
System.out.print(obj1);
}
}
package com.cs.dynamic;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class DirClassLoader extends ClassLoader
{
/**
* 类加载器的核心代码 -加载类在需要的时候自动编译源文件。
* @param pkgDir 包所在路径,以“/”结束
* @param name 类名称,包括所在包名称,例如com.cs.worker.worker1
* @param resolve 是否解释类
* @throws ClassNotFoundException
* @return Class
*/
public Class loadClass(String pkgDir, String name, boolean resolve) throws ClassNotFoundException
{
//我们的目的是获得一个类对象。
Class clas = null;
// 首先,检查是否已经出理过这个类。
clas = findLoadedClass(name);
if(clas != null)
{
//System.out.println("finded Class: " + clas);
//return clas;
}
// 通过类名获得路径名比如:java.lang.Object => java/lang/Object
String fileStub = name.replace('.', '/');
// 构建指向类文件的对象。
String classFilename = pkgDir + fileStub + ".class";
File classFile = new File(classFilename);
if (classFile.exists())
// 我们开始加载原始字节。
try
{
// 读取字节。
byte raw[] = getBytes(classFilename);
// 转化为类对象
//System.out.println("load " + name + " from DirClassLoader");
clas = defineClass(name, raw, 0, raw.length);
}
catch (IOException ie)
{
// 这里并不表示失败,可能我们处理的类在本地类库中,如java.lang.Object。
}
//System.out.println( "defineClass: "+clas );
//可能在类库中,以默认的方式加载。
if (clas == null)
{
//System.out.println("load " + name + " from SysClassLoader");
clas = findSystemClass(name);
}
//System.out.println( "findSystemClass: "+clas );
// 如果参数resolve为true,根据需要解释类。
if (resolve && clas != null)
resolveClass(clas);
// 如果还没有获得类,说明出错了。
if (clas == null)
throw new ClassNotFoundException(name);
// 否则,返回这个类对象。
return clas;
}
/**
* 指定一个文件名,从磁盘读取整个文件内容,返回字节数组。
* @param filename String
* @throws IOException
* @return byte[]
*/
private byte[] getBytes(String filename) throws IOException
{
// 获得文件大小。
File file = new File(filename);
long len = file.length();
//创建一个数组刚好可以存放文件的内容。
byte raw[] = new byte[ (int) len];
// 打开文件
FileInputStream fin = new FileInputStream(file);
// 读取所有内容,如果没法读取,表示发生了一个错误。
int r = fin.read(raw);
if (r != len)
throw new IOException("Can′t read all, " + r + " != " + len);
// 别忘了关闭文件。
fin.close();
// 返回这个数组。
return raw;
}
}
// ------------------------ WorkerFactory ----------------------
package com.cs.dynamic;
public class WorkerFactory
{
@SuppressWarnings("unchecked")
public static Class getClassByName(String pkgDir, String className)
{
Class ret = null;
try
{
DirClassLoader dcl = new DirClassLoader();
ret = dcl.loadClass(pkgDir, className, false);
}
catch(Exception e)
{
e.printStackTrace();
}
return ret;
}
}
// ------------------------ WorkerManager --------------------------
package com.cs.dynamic;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class WorkerManager
{
@SuppressWarnings("unchecked")
public static Object invoke(Class clazz, String funcName, Params ps) throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
Object ret = null;
Class[] partypes = new Class[1];
partypes[0] = Params.class;
Method mth = clazz.getMethod(funcName, partypes);
Object arglist[] = new Object[1];
arglist[0] = ps;
Object methobj = clazz.newInstance();
ret = mth.invoke(methobj, arglist);
return ret;
}
}
// -------------------------- Params -------------------------------------
package com.cs.dynamic;
import java.util.ArrayList;
public class Params extends ArrayList<Param>
{
private static final long serialVersionUID = -2705421853334947899L;
public String getValueByName(String name)
{
String value = "";
if (name == null)
return value;
if ("".equals(name))
return value;
for (int n = 0; n < size(); n ++)
{
Param p = (Param)get(n);
if (name.equalsIgnoreCase(p.Name))
{
value = p.Value;
break;
}
}
return value;
}
}
// ------------------------ Param -----------------------------
package com.dynamic;
public class Param
{
public String Name = "";
public String Value = "";
}
// ---------------------- 测试 ------------------------------------
package com.cs.workers;
import com.cs.dynamic.Params;
public class Worker1
{
public String test(Params ps)
{
for (int n = 0; n < ps.size(); n ++)
System.out.println(ps.get(n).Name + "=" + ps.get(n).Value);
return "Hello!";
}
}
// ------------------- 测试代码 ---------------------------
import java.lang.reflect.InvocationTargetException;
import com.cs.dynamic.Param;
import com.cs.dynamic.Params;
import com.cs.dynamic.WorkerFactory;
import com.cs.dynamic.WorkerManager;
public class test {
/**
* @param args
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws IllegalArgumentException
* @throws SecurityException
*/
public static void main(String[] args) throws SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
{
// TODO Auto-generated method stub
//System.out.println(System.getProperty("user.dir"));
String dir = System.getProperty("user.dir") + "/bin/";
Class obj = WorkerFactory.getClassByName(dir, "com.cs.workers.Worker1");
Params ps = new Params();
Param p = new Param(); p.Name = "123"; p.Value = "dsa";
ps.add(p);
Object obj1 = WorkerManager.invoke(obj, "test", ps);
System.out.print(obj1);
}
}
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步