第一次使用Sprig Boot, 正当我折服于他的强大时,老板跟我说,你要写一个基于Spring boot的runner, 然后小A会写一个SDK,你把SDK依赖进去就可以了。 我: 什么,我就写一个runner,然后就没有然后了。 他: 当然不是,你还要写配置呢, 所有的配置文件。 我: 好吧好吧,你是老板,你说咋写就咋写。
但是我不能就没有然后了呀,我可是一个上进的好少年,Spring boot本身打出来的包就是可以运行的,我这个runner不是多余的吗, 它不会糊涂吗?抱着这个想法, 我在本地试了一下,果然,引入依赖后根本无法识别包在哪里。 这是为什么呢,那我们一点点来看哈。
假设项目结构
<groupId>com.shuanger</groupId>
<artifactId>package_example</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
Spring boot 生成可执行的jar包
无论你用什么方式创建的spring boot应用,你应该都会看到下面的maven依赖,这个spring-boot-maven-plugin是用来干什么的呢?他就是用来的maven package基础上,再一次的专门为spring boot再打一次包,俗称repackage。
maven 配置
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
此时运行mvn package 命令, 会在项目的target目录中看到生成的jar包: package_example-1.0.0.jar, 同时也会看到package_example-1.0.0.jar.original, 该文件仅包含应用本地资源(如编译后的classes目录下的文件),未引入第三方依赖资源,索引占用的空间很小, 我们今天的主角是package_example-1.0.0.jar,此时你进入target目录下,运行如下命令:
java -jar package_example-1.0.0.jar
这就是一个可以执行的jar包
需要注意的使用这种配置的前提是使用了spring-boot-starter-parent作为parent,如果使用的是自己定义的parent,需要修改maven配置如下:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
使用上述配置,也会生成跟前面提到的一样的jar包。
Spring Boot 生成可依赖的jar包
为了生成可以被依赖的jar包,可以采用两种方式,一种方式是使用spring-boot-maven-plugin, 一种是使用maven-jar-plugin。 下面我们分别看一下二者的配置。 首先我们来看看使用Spring-boot-maven-plugin的maven配置:
maven 配置
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
使用上述配置会在target下生成两个jar包,一个是可以被依赖的jar包:package_example-1.0.0.jar。 一个是执行的jar包:package_example-1.0.0-exec.jar。
如上配置打出来的可以被依赖的jar包包含的一些不需要的文件,比如application.properties/application.yml.这些配置文件可能会在引用它的项目中造成不必要的覆盖。 所以我们想排除这是文件,这时就需要使用maven-jar-plugin。 让我们看看使用maven-jar-plugin的maven配置:
maven 配置
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>lib</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>lib</classifier>
<excludes>
<exclude>application.yml</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
使用上述配置,也会在target下生成两个jar包,一个是可以被依赖的jar包:package_example-1.0.0-lib.jar。 一个是执行的jar包:package_example-1.0.0.jar.那生成的可执行的jar包和可被依赖的jar包有什么区别呢。来让我们看一看两个包的结构:
可执行的jar包:
可被依赖的jar包
看到没,可执行的jar包多了一个BOOT-INF目录,
- BOOT-INF/classes目录存放应用编译后的class文件
- BOOT_INF/lib目录存放应用依赖的jar包
- META-INF/目录存放应用相关的元信息,如MANIFEST.MF文件
- org/目录存放Spring Boot相关的class文件
这里需要注意的是引用使用了classifier生成的包时,如可被依赖的package_example-1.0.0-lib.jar包时要加入classifier,配置如下:
<dependency>
<groupId>com.shuanger</groupId>
<artifactId>package_example</artifactId>
<version>1.0.0</version>
<classifier>lib</classifier>
</dependency>
好了,今天的Spring boot打包就写到这里,如果有新的发现我会继续补充。