Tomcat与Spring-Web模块加载:SPI机制下的类加载行为分析
Tomcat加载Spring-Web模块时,利用Java SPI(Service Provider Interface)机制查找并使用ServletContainerInitializer接口的实现类。 这涉及到ServiceLoader的load方法和类加载器的可见性原则。 有人质疑这种方式违反了类加载器的可见性原则,让我们深入分析。
文章指出,ServiceLoader.load方法最终由sun.misc.Launcher.AppClassLoader加载ServletContainerInitializer接口的实现类。代码中,ServiceLoader.load(service, cl) 使用Thread.currentThread().getContextClassLoader() 获取类加载器,在Tomcat等应用服务器中,该类加载器通常是AppClassLoader。
有人认为ServiceLoader.load(service, cl) 等同于 ServiceLoader.load(service, null)。虽然在某些情况下结果相似,但原理不同。前者明确指定类加载器,而后者使用调用者的类加载器。
立即学习“Java免费学习笔记(深入)”;
为什么有人认为这破坏了类加载器的可见性原则?关键在于SPI机制的特殊性。rt.jar 中的接口由BootstrapClassLoader加载,但其实现类通常在classpath中,由AppClassLoader加载。BootstrapClassLoader无法向下委托加载,因此需要线程上下文类加载器加载实现类。 这绕过了双亲委派模型的严格层次,使AppClassLoader能够加载BootstrapClassLoader无法加载的类。虽然解决了问题,但也偏离了双亲委派模型的本意。
需要强调的是,AppClassLoader并没有直接跳过双亲委派机制的代码,它内部仍然遵循双亲委派逻辑。只是在SPI场景下,由于BootstrapClassLoader的限制,最终加载工作由AppClassLoader完成,这是一种权衡之举。 JDBC机制类似,Java只提供接口,具体实现由厂商提供,同样需要绕过双亲委派机制的限制。
因此,SPI机制在某种程度上“违反”了双亲委派模型的严格规则,但这是一种必要的妥协,并非完全“破坏”了类加载器的可见性原则。它通过线程上下文类加载器找到了加载实现类的合适途径。
以上就是Tomcat加载Spring-Web模块时,SPI机制真的破坏了Java类加载器的可见性原则吗?的详细内容,更多请关注【创想鸟】其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。
发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/3174564.html