核心类:
package com.zizhu.util; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLStreamHandlerFactory; import java.util.HashSet; import java.util.Set; /** * 自定义类加载器,重载URLClassLoader大部分方法,将jar文件添加到ClassLoader,将jar包路径下所有jar包添加到 * ClassLoader,将ClassPath路径下所有的类以及资源加载到ClassLoader * @author 紫竹 * */ public class MyClassLoader extends URLClassLoader { private Set<String> names = new HashSet<String>();// 存放自定义类的名称 public MyClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { super(urls, parent, factory); } public MyClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); } public MyClassLoader(URL[] urls) { super(urls); } /** * url 既可以是一个文件路径(这个文件路径必须是url格式),里面存放了资源文件,存放了类;也可以是一个jar文件的url格式 * @param urls */ public void addURL(URL... urls){ for (URL url : urls) { System.out.println("加载类路径:" + url.toString()); super.addURL(url); } } /** * 加载jar文件到ClassLoader * @param files */ public void addJar(File... files){ if(files == null || files.length == 0) return ; for(File file : files){ try { addURL(file.toURI().toURL()); } catch (MalformedURLException e) { e.printStackTrace(); } } } /** * 加载ClassPath到ClassLoader,classPath下所有的资源文件,类全部加载到ClassLoader * @param classPath 类路径 */ public void addClassPath(String classPath){ if(isEmpty(classPath)) return; addClassPath(new File(classPath)); } /** * 添加类路径到ClassLoader * @param path */ public void addClassPath(File path){ if(path.isFile()) return; try { addURL(path.toURI().toURL()); } catch (MalformedURLException e) { e.printStackTrace(); } } /** * 添加jar包的路径,即我们所说的lib包 * @param path */ public void addJarPath(File path){ URL []urls = Path2URL(path); if(urls == null || urls.length == 0) return ; addURL(urls); } /** * @param path jar包路径 * @return ClassLoader支持的URL数组 */ public static URL[] Path2URL(File path){ if(path.isFile()) return new URL[0]; File files[] = path.listFiles(); URL urls [] = new URL[files.length]; for(int i = 0;i<files.length;i++){ try { urls[i] = files[i].toURI().toURL(); } catch (MalformedURLException e) { e.printStackTrace(); } } return urls; } @Override public URL findResource(String name) { System.out.println("查找资源:" + name); return super.findResource(name); } private boolean isEmpty(String classPath) { if(classPath != null && classPath.trim().length() > 0) return false; return true; } }通过这个类,能将用户指定的jar包,classpath下用户的所有类手动加载到classLoader,这个类增强了很多URLClassLoader的方法,使得它更好理解,更好使用
调用web业务逻辑类:
package com.zizhu; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import com.zizhu.util.ConfigUtil; import com.zizhu.util.MyClassLoader; public class WebToNative { public void startToRun(){ String libPath = ConfigUtil.getValue("libPath"); String mainClass = ConfigUtil.getValue("mainClass"); String homePath = ConfigUtil.getValue("homePath"); String methodName = ConfigUtil.getValue("methodName"); try { File lib = new File(libPath); File files[] = lib.listFiles(); URL []urls = MyClassLoader.Path2URL(new File(libPath)); MyClassLoader loader = new MyClassLoader(urls, Thread.currentThread().getContextClassLoader()); //三种方式都可以,都是添加类路径 // loader.addURL(new File(homePath).toURI().toURL()); // loader.addClassPath(new File(homePath)); loader.addClassPath(homePath); Thread.currentThread().setContextClassLoader(loader); Class clazz = loader.loadClass(mainClass); Method m = clazz.getMethod(methodName, null); m.invoke(clazz.newInstance(), null); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } }
1.测试类:
package com.zizhu; public class Test { public static void main(String args[]){ new WebToNative().startToRun(); } }
libPath=D:/Java/WorkspaceForMyeclipse/exam2.0/WebRoot/WEB-INF/lib/ homePath=D:/Java/WorkspaceForMyeclipse/exam2.0/WebRoot/WEB-INF/classes/ mainClass=com.onnet.utils.schedule.ExamTipAndDeleteSchedule methodName=tipAndDelete
1.首先会用自定义的MyClassLoader去加载libPath下所有的jar包
2.加载jar包后,必须把web程序的classpath,也就是源码的类加入到classLoader,homePath,这样,自定义的MyClassLoader就能找到web程序所有的资源,web程序运行的类(也就是web程序需要执行的业务逻辑)
3.然后将自定义的这个MyClassLoader设置为当前线程的ClassLoader
4.最后采用反射机制调用web的业务逻辑类,以及业务逻辑的某个方法