在生产中不使用 spring-boot 类加载器有什么注意事项吗?

问题描述 投票:0回答:1

什么

我想用

jdk.internal.loader.ClassLoaders$AppClassLoader
代替弹簧靴
org.springframework.boot.loader.LaunchedURLClassLoader
。但是,我不确定这将如何影响 spring-boot 运行时。

为什么

我们最近在 java 的

java.lang.InstantiationError
内进行 Spring 存储库调用时遇到了
parallelStream()
。我了解到并行流中的线程正在使用
AppClassLoader
,因此无法找到位于
LaunchedURLClassLoader
(类加载器层次结构中
AppClassLoader
的子级)中的应用程序类。

如何

spring-boot 文档 显示您可以在不使用类加载器的情况下运行解压的 spring-boot jar。这很方便地意味着应用程序类也被加载到

AppClassLoader
中,从而解决了
parallelStream()
的问题。

$ java -cp BOOT-INF/classes:BOOT-INF/lib/* com.example.MyApplication

NB:这也是 Intellij IDEA 运行 spring-boot 应用程序的方式。

问题

谁知道 spring-boot 类加载器是否所做的不仅仅是启用我应该了解的可执行 jar 和 war 文件。我发现文档不够明确。在生产中使用 spring-boot 类加载器是否安全?

java spring-boot classloader classloading
1个回答
0
投票

我还遇到了间歇性问题,突然使用 AppClassLoader 而不是 LaunchedURLClassLoader(甚至在并行执行之外),导致找不到资源。

最新版本的文档有一个“高效部署”部分,表示运行解压的存档会更快。

某些 PaaS 实现也可能选择在运行之前解压存档。例如,Cloud Foundry 就是这样运作的。

知道了这一点,我可以说在生产中这样做绝对是
安全的。 我什至会说它更安全,因为它在运行时会更简单,但这是我的拙见。

还补充说:

解压 jar 文件后,您还可以通过使用其“自然”主方法运行应用程序来获得额外的启动时间 [...]:

$ jar -xf myapp.jar $ java -cp "BOOT-INF/classes:BOOT-INF/lib/*" com.example.MyApplication

正如你所说,这方便地意味着我们摆脱了 Spring Boot 自定义 ClassLoader!
只有一个注释:

在应用程序的 main 方法上使用 JarLauncher 具有可预测的类路径顺序的额外好处。该 jar 包含一个 classpath.idx 文件,JarLauncher 在构建类路径时使用该文件。

因此,在使用“自然”的 main 方法时,请注意不可预测的类路径顺序。这似乎是唯一的缺点。

更进一步:


查看扩展了

URLClassLoader

LaunchedURLClassLoader,并分析 LaunchedURLClassLoaderTests 中的测试,我可以说它只是添加了处理 JAR 资源加载和嵌套 JAR 的逻辑。过去曾通过添加“快速异常”机制修复了像#4582这样的性能问题。

© www.soinside.com 2019 - 2024. All rights reserved.