默认打包方式pom文件啥也不配置:
打包后目录结构如下:
仅打包项目中的代码到 JAR 包中,不打包依赖包,打包后的jar解压文件目录
# 先执行 clean,再执行 package,并且跳过测试用例的执行
mvn clean package -Dmaven.test.skip
项目的依赖都在maven中 的pom文件中无法独立运行
pom文件中添加名称可以修改打包后的jar名称
<build>
<finalName>idongjia</finalName>
</build>
第一种springboot项目将项目完整打包插件
<build>
<finalName>idongjia</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
打包后目录结构如下和MANIFEST.MF文件:
是可以使用 java -jar idongjia.jar 直接执行的
BOOT-INF是可运行jar包才有的,里面classes目录是咱们写的代码的classs文件,另一个lib就是其他依赖jar包的位置;
MANIFEST.MF文件
java -jar会去找jar中的MANIFEST.MF文件的Main-Class,在那里面找到真正的启动类;
使用spring-boot-maven-plugin插件用于将项目打包为可执行 Jar 包,不建议再使用其他任何插件
方法二:使用 maven-jar-plugin 和 maven-dependency-plugin 插件
<build>
<!--项目打包成的名字-->
<finalName>idongjia</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<!--会在MANIFES.MF中生成Class-Path项目-->
<!--系统会根据Class-Path 项配置的路径加载依赖 -->
<addClasspath>true</addClasspath>
<!--指定依赖包所在目录,相对于项目最终Jar包的路径 -->
<classpathPrefix>lib/</classpathPrefix>
<!--指定MainClass -->
<mainClass>com.idongjia.MySpringBootApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!--配置依赖包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<!--相当于执行mvn 命令将依赖包打包到指定目录 -->
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!--将依赖包打包到target下的指定lib目录-->
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
打包后的jar项目结构和对应的 MANIFEST.MF结构
首先说 maven-jar-plugin 插件,它的思想就是:指定启动类、指定依赖包相对于项目最终 Jar 包所在的路径、给 MANIFEST.MF 文件添加 Class-Path 属性(运行项目 Jar 包时会根据 Class-Path 属性来找到具体依赖 Jar 包的路径)。
接着是 maven-dependency-plugin 插件,它的主要思想就是:指定所有依赖被打包为 Jar 包后的存放路径。
# 先执行 clean,再执行 package,并且跳过测试用例的执行
mvn clean package -Dmaven.test.skip
打包完成后,会在项目的 target
目录下生成 lib
文件夹(存放项目的所有依赖)和项目的 Jar 包:
方法三:使用 maven-assembly-plugin 插件
<build>
<!-- 项目最终打包成的名字 -->
<finalName>idongjia</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<!-- 指定启动类 -->
<manifest>
<mainClass>com.idongjia.MySpringBootApplication</mainClass> </manifest>
</archive>
<!-- 指定启动类 -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<!-- 相当于在执行 package 打包时,在后面加上 assembly:single -->
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
使用 maven-assembly-plugin
插件打出来的包只有一个 Jar 包
这个 Jar 包中包含了项目代码以及依赖的代码。可以直接通过 java -jar idongjia.jar
的命令来运行。
这个插件的使用思想也比较简单:首先还是指定启动类;然后配置描述符参数,这个是插件提供的预置参数,不用更改;接下来就是打包时追加的命令了。
然后执行 Maven 打包命令:
# 先执行 clean,再执行 package,并且跳过测试用例的执行
mvn clean package -Dmaven.test.skip
方法三:使用 maven-shade-plugin 插件
<build>
<!-- 项目最终打包成的名字 -->
<finalName>idongjia</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<!-- 下面的配置仅针对存在同名资源文件的情况,如没有则不用配置-->
<!-- 有些项目包可能会包含同文件名的资源文件(例如属性文件)-->
<!-- 为避免覆盖,可以将它们的内容合并到一个文件中 -->
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<!-- 指定启动类 -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.idongjia.MySpringBootApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
可以将项目的依赖以及项目的源码打包成一个可执行 Jar 包
指定项目的启动类;然后就是配置一个文件合并操作,主要是因为有的项目可能会有重名的资源文件,为了避免前面的资源文件被后面的覆盖掉,可以将重名的配置文件合并为一个文件,对于无重名资源文件的项目则无需配置。
# 先执行 clean,再执行 package,并且跳过测试用例的执行
mvn clean package -Dmaven.test.skip
打包后目录结构如下和MANIFEST.MF文件:
Spring Boot 的 Jar 包可以直接运行的原因:org.springframework.boot.loader.Launcher
类是 Spring Boot Jar 包实际的主类,负责调用应用的 main 方法。Launcher
类有三个子类:JarLauncher
,WarLauncher
和 PropertiesLauncher
,由它们负责从 jar 包或者 war 包中读取内嵌的资源
JarLauncher
从 BOOT-INF/lib/
固定路径加载资源;WarLauncher
是从 WEB-INF/lib/
和 WEB-INF/lib-provided/
路径。
PropertiesLauncher
默认从 BOOT-INF/lib/
加载资源,并且支持通过环境变量 LOADER_PATH
或 loader.path
来指定额外的路径。
具体的 Launcher 和应用的 main 函数所在类,设定在 MANIFEST.MF
文件中,一般由 Maven 或 Gradle 打包插件帮我们设定好,例如: