利用ClasserLoader实现jar包加载并调用里面的方法
作者:HBLOG
classloader即是类加载,虚拟机把描述类的数据从class字节码文件加载到内存,并对数据进行检验、转换解析和初始化,了解java的类加载机制,可以快速解决运行时的各种加载问题并快速定位其背后的本质原因,本文介绍了如何利用ClasserLoader来实现jar包加载并调用里面的方法
1.ClasserLoader介绍?
classloader顾名思义,即是类加载。虚拟机把描述类的数据从class字节码文件加载到内存,并对数据进行检验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。了解java的类加载机制,可以快速解决运行时的各种加载问题并快速定位其背后的本质原因,也是解决疑难杂症的利器。因此学好类加载原理也至关重要。
内置类加载器
JVM 中内置了三个重要的 ClassLoader
:
BootstrapClassLoader
(启动类加载器):最顶层的加载类,由 C++实现,通常表示为 null,并且没有父级,主要用来加载 JDK 内部的核心类库(%JAVA_HOME%/lib
目录下的rt.jar
、resources.jar
、charsets.jar
等 jar 包和类)以及被-Xbootclasspath
参数指定的路径下的所有类。ExtensionClassLoader
(扩展类加载器):主要负责加载%JRE_HOME%/lib/ext
目录下的 jar 包和类以及被java.ext.dirs
系统变量所指定的路径下的所有类。AppClassLoader
(应用程序类加载器):面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。
除了这三种类加载器之外,用户还可以加入自定义的类加载器来进行拓展,以满足自己的特殊需求。就比如说,我们可以对 Java 类的字节码( .class
文件)进行加密,加载时再利用自定义的类加载器对其解密。
2.代码工程
实验目标
实现加载外部jar包,并调用其中类方法
JarLoader
package com.et; import java.net.URL; import java.net.URLClassLoader; import java.lang.reflect.Method; import java.io.File; public class JarLoader { private URLClassLoader urlClassLoader; // load JAR file public void loadJar(String jarFilePath) throws Exception { File jarFile = new File(jarFilePath); URL jarUrl = jarFile.toURI().toURL(); urlClassLoader = new URLClassLoader(new URL[]{jarUrl}, this.getClass().getClassLoader()); System.out.println("JAR Loaded: " + jarFilePath); } //load class from JAR and invoke method public void invokeClassMethod(String className, String methodName) throws Exception { if (urlClassLoader != null) { Class<?> loadedClass = urlClassLoader.loadClass(className); Method method = loadedClass.getDeclaredMethod(methodName); method.invoke(loadedClass.newInstance()); System.out.println("Method Invoked: " + methodName); } else { System.out.println("ClassLoader is null, load a JAR first."); } } // unload JAR public void unloadJar() throws Exception { if (urlClassLoader != null) { urlClassLoader.close(); // close ClassLoader urlClassLoader = null; // let it recycle by jvm System.out.println("JAR Unloaded."); } else { System.out.println("No JAR to unload."); } } }
service(demo模块)
创建sevice类
mvn install
打包成jar包package com.et.demo.service;
public class MockService implements Service { @Override public void printVersion() { System.out.println("11.0"); } }
package com.et.demo.service;
public interface Service { void printVersion(); }
以上只是一些关键代码,所有代码请参见下面代码仓库
代码仓库
- https://github.com/Harries/Java-demo(classloader)
3.测试
编写测试类
package com.et; public class Main { public static void main(String[] args) throws Exception { JarLoader jarLoader = new JarLoader(); // load JAR jarLoader.loadJar("D:\\IdeaProjects\\Java-demo\\demo\\target\\demo-1.0-SNAPSHOT.jar"); // invoke the method jarLoader.invokeClassMethod("com.et.demo.service.MockService", "printVersion"); // unload JAR jarLoader.unloadJar(); } }
启动main方法,查看日志
JAR Loaded: D:\IdeaProjects\Java-demo\demo\target\demo-1.0-SNAPSHOT.jar 11.0 Method Invoked: printVersion JAR Unloaded. Disconnected from the target VM, address: '127.0.0.1:53226', transport: 'socket' Process finished with exit code 0
到此这篇关于利用ClasserLoader实现jar包加载并调用里面的方法的文章就介绍到这了,更多相关ClasserLoader jar包加载并调用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!