Hello! 欢迎来到小浪资源网!


Java SPI机制下ServiceLoader加载类是否违反类加载器可见性原则?


Java SPI机制下ServiceLoader加载类是否违反类加载器可见性原则?

Java类加载器可见性原则

问题:

在加载一个接口的实现类时,Java.util.ServiceLoader#load方法使用了sun.misc.Launcher.AppClassLoader类加载器,这是否违背了Java类加载器可见性原则?

回答:

立即学习Java免费学习笔记(深入)”;

要理解这个问题,首先需要了解SPI(服务提供者接口)的机制。SPI是一种Java机制,允许第三方提供程序实现特定接口,并在运行时加载这些实现。

在使用SPI时,Java类加载器会违反可见性原则,因为它会绕过双亲委派机制。正常情况下,类加载器只会从其父加载器中搜索类,但在使用SPI时,类加载器会直接从线程上下文类加载器中搜索实现类,这可能会加载其他类加载器已定义的类。

在给定的代码中,java.util.ServiceLoader#load方法使用了sun.misc.Launcher.AppClassLoader作为线程上下文类加载器来加载ServletContainerInitializer接口的实现类。这个类加载器是Java类加载层次结构中的应用程序类加载器,它是应用程序专用类加载器。

因此,虽然代码中没有显式调用java.lang.ClassLoader#loadClass(java.lang.String, Boolean)方法,但类加载器仍然会执行双亲委派机制。这是因为AppClassLoader是ClassLoader类的顶级抽象类,并且会委托给父加载器(bootstrap加载器),直到找到实现ServletContainerInitializer接口的类。

总之,使用SPI会导致违反Java类加载器可见性原则,因为它使用线程上下文类加载器直接加载实现类,这可能会加载其他类加载器已定义的类。

相关阅读