gpt4 book ai didi

spring-boot - 为什么 Spring Boot 1.4 改变了它的 jar 布局来定位 BOOT-INF 下的应用程序类?

转载 作者:行者123 更新时间:2023-12-03 12:43:57 34 4
gpt4 key购买 nike

(这主要是一个历史问题。Pivotal 建议所有论坛讨论都在 StackOverflow 上进行,这就是我在这里问它的原因。)

Spring Boot 项目用来证明将应用程序的类和依赖项从可执行 jar 格式的“顶层”移动到 BOOT-INF/ 下面的原因是什么? ?

只是想猜测一下,这似乎可以很容易地使用简单的 java -xf the-jar.jar BOOT-INF/classes 从 fat jar 中仅提取与应用程序相关的类和 jar。命令。是这样吗?还有其他原因吗?

最佳答案

TL;博士
在 jar 的根目录中打包应用程序类需要 Spring Boot 的类加载器使用非常规的委托(delegate)模型,并且还会导致 Java 代理出现问题。
详细解释
当使用 java -jar 启动 jar 文件时jar 根目录中的所有类都在系统类加载器的类路径上。在 Spring Boot fat jar 中,这包括启动器的类,该类负责创建一个类加载器,该类加载器可以加载应用程序的类及其嵌套在 fat jar 中的依赖项。
在 Spring Boot 1.3 及更早版本中,应用程序类被打包在一个 fat jar 文件的根目录中。这意味着它们位于系统类加载器的类路径上。使用标准的父优先委托(delegate)模型,这意味着应用程序类将由系统类加载器而不是 Spring Boot 的类加载器加载。这是有问题的,因为只有 Spring Boot 的类加载器可以从嵌套在 fat jar 中的依赖项加载类。结果是应用程序无法加载其任何依赖项的类。
Spring Boot 1.3 通过对其类加载器使用非常规的委托(delegate)模型克服了这个问题。它使用来自系统类加载器的 URL 创建了一个新的类加载器,但不使用系统类加载器作为父类——而是使用系统类加载器的父类。这意味着 Spring Boot 的类加载器将用于将应用程序的类加载到 jar 的根目录中,并将应用程序依赖项的类加载到嵌套的 jar 中。
这种方法有一些缺点。首先是它使 Spring Boot 的类加载器变得相当复杂。第二个是它打破了 Java 代理关于如何加载其类的许多假设。我们解决了其中的几个问题,但很明显我们正在打一场失败的战斗。
Spring Boot 1.4 重新排列了一个胖 jar 以将应用程序类放置在 BOOT-INF/classes 中(它还将嵌套的 jar 移动到 BOOT-INF/lib,但从类加载的角度来看这没有影响)。将应用程序类移动到 BOOT-INF/classes意味着它们不再位于系统类加载器的类路径上。这意味着 Spring Boot 的类加载器可以配置为从 BOOT-INF/classes 加载类。以及从 BOOT-INF/lib 中的 jar 中并使用系统类加载器作为其父级。 Java 代理可以打包在 jar 的根目录中,系统类加载器将照常从那里加载它们。
如需进一步阅读,您可能对 the commit that introduced the change 上的消息感兴趣以及它所链接的其他问题。

关于spring-boot - 为什么 Spring Boot 1.4 改变了它的 jar 布局来定位 BOOT-INF 下的应用程序类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40292816/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com