在spring boot里,很吸引人的一个特性是可以直接把应用打包成为一个jar/war,然后这个jar/war是可以直接启动的,而不需要另外配置一个Web Server。那么spring boot如何启动的呢?今天我们就来一起探究一下它的原理。首先我们来创建一个基本的spring boot工程来帮助我们分析,本次spring boot版本为 2.2.5.RELEASE。
// SpringBootDemo.java @SpringBootApplication public class SpringBootDemo { public static void main(String[] args) { SpringApplication.run(SpringBootDemo.class); } }
下面是pom依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <finalName>springboot-demo</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
创建完工程后,执行maven的打包命令,会生成两个jar文件:
springboot-demo.jar
springboot-demo.jar.original
其中springboot-demo.jar.original
是默认的maven-jar-plugin
生成的包。springboot-demo.jar是spring boot maven插件生成的jar包,里面包含了应用的依赖,以及spring boot相关的类。下面称之为executable jar或者fat jar。后者仅包含应用编译后的本地资源,而前者引入了相关的第三方依赖,这点从文件大小也能看出。
关于executable jar,spring boot官方文档中是这样解释的。
Executable jars (sometimes called “fat jars”) are archives containing your compiled classes along with all of the jar dependencies that your code needs to run.
Executable jar(有时称为“fat jars”)是包含您的已编译类以及代码需要运行的所有jar依赖项的归档文件。
Java does not provide any standard way to load nested jar files (that is, jar files that are themselves con来1源gaodai#ma#com搞*代#码1网tained within a jar). This can be problematic if you need to distribute a self-contained application that can be run from the command line without unpacking.
Java没有提供任何标准的方式来加载嵌套的jar文件(即,它们本身包含在jar中的jar文件)。如果您需要分发一个自包含的应用程序,而该应用程序可以从命令行运行而无需解压缩,则可能会出现问题。
To solve this problem, many developers use “shaded” jars. A shaded jar packages all classes, from all jars, into a single “uber jar”. The problem with shaded jars is that it becomes hard to see which libraries are actually in your application. It can also be problematic if the same filename is used (but with different content) in multiple jars.
为了解决这个问题,许多开发人员使用 shaded jars。 一个 shaded jar 将来自所有jar的所有类打包到一个 uber(超级)jar 中。 shaded jars的问题在于,很难查看应用程序中实际包含哪些库。 如果在多个jar中使用相同的文件名(但具有不同的内容),也可能会产生问题。
Spring Boot takes a different approach and lets you actually nest jars directly.
Spring Boot采用了另一种方法,实际上允许您直接嵌套jar。