我们在程序开发完成交付之后有些客户会有扩展的需求,因为任何系统的生命周期中都是不断完善,不断扩展的,没有系统是交付后一成不变的,因为随着企业业务的发展及初始业务涉及的不完善都会随着时间一点点爆露出来,所以需要灵活的对系统进行扩展,并且在不影响已有程序,所以插件是一个很好的解决办法,它既可以动态添加也可以动态移出。 今天我们就来写一个简单的例子来演示如何通过classloader加载jar并执行类的方法,以及和Class.forName()的区别。
先写一个简单的代码,并制作jar包
package com.demo.simple; public class Aaa { public String getMessage(){ return "helloword"; } }
我们在写一个ClassLoader来执行这个jar包aa.jar
package org.dbzy.classloader; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; public class Aaa { public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { String dir = "C:\\aa.jar"; File file = new File(dir); URL url = file.toURI().toURL(); ClassLoader loader = new URLClassLoader(new URL[] { url }); Class<?> cls = loader.loadClass("com.demo.simple.Aaa"); Object obj = cls.newInstance(); Method method = cls.getMethod("getMessage"); Object o = method.invoke(obj); System.out.println(String.valueOf(o)); } }
通过以上的方式就可以执行了。
下面我们来整理classloader和class.forName的区别
1.Class.forName返回的Class对象可以决定是否初始化。而ClassLoader.loadClass返回的类型绝对不会初始化,最多只会做连接操作。
2.Class.forName可以决定由哪个classLoader来请求这个类型。而ClassLoader.loadClass是用当前的classLoader去请求。