我正在开发一个简单的插件系统,我基本上想控制哪个类加载器在一条new指令上加载一个类.例如,我的主程序有一个jar,我Foo.class在一个名为的额外打包jar中分发一个类Bar.jar.
我看到在我的主程序中包含jar的三种不同的可能性:
Bar.jar用我的主要罐子将其包含在类路径中.对于插件系统来说,这显然是不可行的Foo与URL的ClassLoader指着罐子.这对于默认的java程序员来说太熟悉,无法通过名称手动加载类-Djava.system.class.loader参数将自定义类加载器设置为System-classloader .但我真的不想强迫用户使用额外的参数启动他的应用程序.还有另外一种方法吗?也许是为特定类注册Custom类加载器的东西?或更改Classloader new在运行时使用?设置ContextClassLoader的Thread不工作.
加载类时,它引用的类使用与它相同的类加载器.这意味着要隐式控制使用的类加载器,您可以使用不同的类加载器来启动它.例如你的第一个Runnable.
class A {
B b = new B();
Run Code Online (Sandbox Code Playgroud)
的new B意志选择用于A类加载器(或父)
设置上下文类加载器适用于动态查找喜欢Class.forName(name);是一样的Class.forName(Thread.currentThread().getContextClassLoader(), name);
一旦加载了类,它将始终使用它所依赖的相同类.根据线程上下文说,不可能交换不同的类.这意味着具有非常特定的类加载器的类可以使用更常用的类(例如,通用类来自父类),但是更通用的类不能使用它不知道的更具体的类加载器.即ClassLoaders不知道他们的孩子.
其中一个原因是线程共享内存.这意味着你不能说当A在一个线程中创建一个新的B时,它将与另一个线程不同,因为任何一个线程都可以访问A实例.