自定义ClassLoader,如何使用?

时间:2017-08-13 03:39:00

标签: java classloader dynamic-class-loaders

我正在尝试使用自定义类加载器来加载应用程序所需的所有依赖项。我在网站后面实现了customerClassLoader:https://www.javacodegeeks.com/2013/03/java-handmade-classloader-isolation.html

但是,我不明白如何告诉我的应用程序在需要时使用自定义classLoader。

例如:让我们说,我有一个方法来发出如下的http请求。如何告诉应用程序使用自定义classLoader加载所需的jar?

private HttpResponse get() {
    HttpClient client = HttpClientBuilder.create().build();
    HttpGet request = new HttpGet(url);
    HttpResponse response = client.execute(request);
    return response;
}

2 个答案:

答案 0 :(得分:2)

当您使用 static long getFolderSize(string path) { DirectoryInfo dirInfo = new DirectoryInfo(path); long b = 0; foreach(FileInfo fi in dirInfo.EnumerateFiles("*",SearchOption.AllDirectories)) { b += fi.Length; } return b; } ClassLoader关键字时,Java隐式使用new,jvm将使用当前类的类加载器来加载依赖类,因此您可以使用自定义类加载器来加载使用import显式bootstrap类,而classloader.loadclass只运行属于目标类实例的方法。下面是一个例子。

有一个班级bootstrap取决于Target中包含的班级DateFormatter,并且有一个名为spring-context的方法。

start

接下来,我们将上述代码编译并打包为名为import org.springframework.format.datetime.DateFormatter; public class Target { private static DateFormatter dateFormatter; public void start(){ System.out.println(this.getClass().getClassLoader()); dateFormatter=new DateFormatter(); System.out.println(dateFormatter); } } 的jar,该jar存储在target.jar

接下来,我们在另一个jar中声明一个类D:\\test\\target.jar,它将调用BootStrap实例的方法startTarget类将通过BootStrap实例target.jar动态加载spring-contextclassloader jar文件。因此,URLClassLoader实例中的方法start可以访问Target中定义的DateFormatter类。

spring-context

最后,运行public class BootStrap { public static void main(String[] args) throws Exception{ URL url = new URL("http://maven.aliyun.com/nexus/content/groups/public/org/springframework/spring-context/4.3.1.RELEASE/spring-context-4.3.1.RELEASE.jar?spm=0.0.0.0.kG1Pdw&file=spring-context-4.3.1.RELEASE.jar"); URL url2= (new File("D:\\test\\target.jar").toURI().toURL()); URLClassLoader classLoader = new URLClassLoader(new URL[]{url,url2}); Class<?> clz = classLoader.loadClass("com.zhuyiren.Target"); Object main = clz.newInstance(); Method test = clz.getMethod("start"); test.invoke(main); } } main方法。有两件重要的事情:

  1. BootStrap类和BootStrap类不属于同一个jar文件。
  2. Target未存储在target.jar路径中。
  3. 这两点可以确保CLASSPATH无法找到并加载AppClassLoader类。由于类加载器的机制,jvm将使用自定义加载Target。当然,您可以通过将Target更改为URLClassLoader classLoader = new URLClassLoader(new URL[]{url,url2});

    来保证这一点

    我们可以看到结果:

    URLClassLoader classLoader = new URLClassLoader(new URL[]{url, url2}, ClassLoader.getSystemClassLoader().getParent());
    

    这意味着我们可以成功访问java.net.URLClassLoader@e9e54c2 org.springframework.format.datetime.DateFormatter@4dd8dc3 jar文件中定义的DateFormatter实例,而spring-context未存储在spring-context中,但我们正在使用自定义clasloader加载和使用它。

答案 1 :(得分:0)

您可以执行以下操作;

Thread.currentThread().setContextClassLoader(new MyCustomClassLoader());