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


Java SPI机制:真的会打破类加载器可见性原则吗?


Java SPI机制:真的会打破类加载器可见性原则吗?

Java中spi机制是否打破类加载器可见性原则

java中的类加载器遵循可见性原则,即类加载器只能加载其父加载器或自身加载的类。然而,有文章提出,java中的服务提供者接口(spi)机制可能会破坏此原则。

使用spi机制的代码片段

public static <S> ServiceLoader<S> load(class<S> service) {     ClassLoader cl = Thread.currentThread().getContextClassLoader();     return ServiceLoader.load(service, cl); }

违反可见性原则的说法

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

该代码使用sun.misc.launcher.appclassloader加载实现了servletcontainerinitializer接口的类。launcher.appclassloader是应用程序类加载器,它不能加载由引导类加载器加载的类。因此,有人认为这违反了可见性原则。

实际情况

事实上,java.util.serviceloader的load方法最终仍会使用双亲委派机制。serviceloader.lazyiterator#nextservice方法中调用class.forname方法加载类,而class.forname会沿着双亲委派链向上委派,直到找到该类为止。

因此,即使使用spi机制,load方法仍然可以通过双亲委派机制加载由其他类加载器加载的类。这不会破坏可见性原则。

打破双亲委派机制的经典范例

虽然spi机制本身不会打破双亲委派机制,但它确实是一个违反此机制的经典范例。这是因为spi允许第三方类加载器加载实现接口的类,而这些类可能无法由引导类加载器或应用程序类加载器直接访问。

相关阅读