专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

利用ClasserLoader来实现jar包加载并调用里面的方法

ins518 2024-11-12 12:27:43 技术文章 10 ℃ 0 评论

1.ClasserLoader介绍?

classloader顾名思义,即是类加载。虚拟机把描述类的数据从class字节码文件加载到内存,并对数据进行检验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。了解java的类加载机制,可以快速解决运行时的各种加载问题并快速定位其背后的本质原因,也是解决疑难杂症的利器。因此学好类加载原理也至关重要。

内置类加载器

JVM 中内置了三个重要的ClassLoader

  1. BootstrapClassLoader(启动类加载器):最顶层的加载类,由 C++实现,通常表示为 null,并且没有父级,主要用来加载 JDK 内部的核心类库( %JAVA_HOME%/lib目录下的 rt.jarresources.jarcharsets.jar等 jar 包和类)以及被 -Xbootclasspath参数指定的路径下的所有类。
  2. ExtensionClassLoader(扩展类加载器):主要负责加载 %JRE_HOME%/lib/ext 目录下的 jar 包和类以及被 java.ext.dirs 系统变量所指定的路径下的所有类。
  3. 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

4.引用

  • https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html
  • http://www.liuhaihua.cn/archives/711389.html

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表