当一个 Web 应用程序被加载时,Tomcat
它是由一个特定的类加载器加载的,对吧?
我假设WEB-INF\lib
此 Web 应用程序使用的所有库(在 下)都由同一个类加载器加载?
在这种情况下,有没有办法在不同的类加载器下加载库而没有任何问题?
我想这样做的原因是因为Axis
使用了一些绑定到类加载器的配置属性,并且希望使用不同的属性进行请求,从而使用不同的类加载器。
这可能吗?
问问题
2232 次
1 回答
3
如果您想在运行时以编程方式加载类,您可以使用 URLClassLoader,但要真正做到正确可能会非常棘手。你会做这样的事情:
URL[] urls = new URL[] {
/* URL to your axis jar */,
/* other URLs you need */
};
URLClassLoader classLoader = new URLClassLoader(urls, getClass().getClassLoader());
Class<...> axisClass = classLoader.findClass(/* fully qualified name */);
然后你应该能够创建这个类的一个新实例并使用它。
编辑:这是一个更具体的示例,尽管没有使用 Axis,因为设置起来太困难了。我创建了一个包含以下类的 JAR 文件:
public class Hello {
public Hello(String config) {
}
public String getMessage() {
return "Hello World";
}
}
我已将此 jar 文件复制到我的测试项目的源文件夹中,因此我可以使用UrlClassloaderTest.class.getResource("hello.jar")
. 在 web 应用程序中,您可能应该将其放入 WebContent/WEB-INF(或类似的东西)并使用该方法javax.servlet.ServletContext.getRealPath("WEB-INF/hello.jar")
找到它。然后我可以使用 URLClassLoader 和反射访问 Hello 类:
public class UrlClassloaderTest {
public static void main(String[] args) throws Exception {
URL jarUrl = UrlClassloaderTest.class.getResource("hello.jar");
URLClassLoader cl = new URLClassLoader(new URL[] { jarUrl }, UrlClassloaderTest.class.getClassLoader());
Class helloClass = cl.loadClass("test.Hello");
Constructor constructor = helloClass.getConstructor(String.class);
Object helloObject = constructor.newInstance("some configuration");
Method messageMethod = helloClass.getMethod("getMessage");
String message = (String) messageMethod.invoke(helloObject);
System.out.println(message);
}
}
请注意,我不能在这里使用 Hello 作为类型,因为它不在应用程序的类路径上,因此类的类加载器不知道它UrlClassLoaderTest
!
于 2012-11-14T06:55:10.373 回答