Spring Boot 项目assembly打包实践
Spring Boot 打包远程执行代码admin 发布于:2022-05-09 10:29:43
阅读:loading
曾经花费好多时间的各种折腾关于打包的实践,主要侧重于三种实现:spring-boot-maven-plugin、appassembler-maven-plugin和maven-assembly-plugin,最终由于几个原因选择了assembly进行实践,在打包本站博客系统时也遇到了一些问题,最终也是友好的解决,在打包时也使用到了maven的其它插件,参考如下:
(1)maven-resources-plugin:在打包或build资源文件时,项目的各种文件会被重新复制生成,某些文件在重新生成的过程中会被改写,追加一些其它的东西后重新生成新文件,如此就导致原有文件的MD5发生了变化,如本站打包时https的证书文件后缀名为“pfx”(证数文件名称为www.chendd.cn.pfx)就被追加生成新文件,所以解决该类问题特增加该插件,排除一些需要过滤的文件,此处的排除并不是不拷贝生成文件,而是排除该类文件被覆盖追加生成新文件,即保持原有文件的拷贝输出,防止造成文件的不可用;
(2)maven-jar-plugin:该插件会将各个module打包为jar文件,同时也可以指定jar文件中的Main-Class启动类,同时可以将resources目录中的某些资源文件或文件夹给排除掉,使得jar包中的文件更加纯粹,可以只包含class和templates以及statics等文件,注意由于该插件在某个module被引用的,排除的文件或文件夹仅只会适用于排除该module下的文件(夹);
(3)copy-rename-maven-plugin和maven-antrun-plugin:拷贝文件并重命名插件,在实践分环境打包时准备用于按分环境的文件夹生成对应的文件,其中有个插件的源代码实现必须限定要重命名的文件必须存在,如果文件不存在不重命名即可,但是抛出错误异常了,导致最终该插件并未使用;
(4)maven-assembly-plugin:Apache打包插件,在打包时同时会先运行(1)(2)的插件,同时运行该插件,该插件使用定制的打包脚本assembly.xml进行深度定制;
(1)打包将resources目录下的配置文件单独存放于conf文件夹,在jar包中不包含配置文件;
(2)打包支持生成新的空白文件夹(配合启动脚本使用,常见的有:logs、runtime、temp等),支持拷贝文件夹和文件至指定位置;
(3)打包若干个jar文件拆成多个文件夹存放,将第三方jar存放于lib-jar、将本地jar(使用systemPath引入的本地路径jar)存放于lib-local、将项目中的各个module的jar存放于lib-project;
(4)打包支持多环境场景,支持不通环境打包,打包时传递不通的环境标识生成对应环境的配置文件;
(1)<finalName>chendd</finalName>标签定义生成打包文件的文件夹前缀名称(见pom.xml文件中引用插件时);
(2)<id>admin</id>标签生成的根文件夹名称为:pom.xml中finalName定义的前缀 + '-' + 此处的id,即打包生成根文件夹为“chendd-admin”;
(3)<format>dir</format>标签指定打包文件夹最终的生成格式,可以是:zip、tar、tar.gz、jar、dir、war等;
(4)<includeBaseDirectory>false</includeBaseDirectory>是否在target目录下创建一个根文件夹,取名<baseDirectory>中的文本;
(5)<baseDirectory>admin-all</baseDirectory>当<includeBaseDirectory>标签为true时有效,会在chendd-admin目录中再生成一个根文件夹,取名为此处定义的admin-all;
(6)<fileSets>指定要包含在程序集中的文件组,指定源文件对应的输出位置和文件权限以及换行符等,支持pom.xml中定义的变量引用,同时可以排除某些文件夹,实现按环境打包的重要标签之一;
(7)<files>创建文件夹以及重命名资源文件,重命名资源文件名称,但当文件不存在时报错了,使用copy-rename-maven-plugin插件解决,同时可以生成空白文件夹;
(8)<dependencySets>处理项目依赖的jar配置,可按jar包路径和依赖jar文件的范围(runtime/test/system等)来筛选文件,实现不同的文件存储到不同的目录中;
打包说明
(1)项目名称为chendd-blog-examples,执行打包时需要执行上图中的“项目pom.xml”,执行时可以同时支持多个module的打包逻辑(本站博客系统2.0会同时打包admin和web相关module,本例只打包admin模块);
(2)在admin模块的/src/main/resources目录下,配置文件为application.yaml和config目录,test目录与prod目录为区分环境打包的目录,此两个目录中包含了全量的配置文件,打包时若不指定环境则默认取/src/main/resources目录中的application.yaml和config目录作为开发环境的打包结果,忽略掉test和prod目录;若打包test环境时将只获取test目录下的所有文件,同时将application-test.yaml文件重命名为application.yaml;若打包prod环境时同样只获取prod目录中的所有文件,将application-prod.yaml重命名为application.yaml;
(3)IDEA有个问题当一个项目模块中若存在多个同名application.yaml时,会导致编写application.yaml内容时无参数代码提示,故本站为了解决此问题,特将不同环境下的此文件均增加了环境标识;
(4)打包命令使用了clean compile package 先清理再编译后打包的步骤,同时区分环境打包使用-P参数,跳过测试的运行使用-Dmaven.test.skip,参考如下:
默认打包开发环境:clean compile package -Dmaven.test.skip=true -f pom.xml
打包test环境:clean compile package -Ptest -Dmaven.test.skip=true -f pom.xml
打包prod环境:clean compile package -Pprod -Dmaven.test.skip=true -f pom.xml
(5)打包需求处的描述均已满足,若本文给出的示例打包时找不到gif包记得关闭maven的offline模式,仅从本地maven仓库中寻找jar;
admin模块pom.xml
<!-- 使用maven-assembly-plugin插件打包 -->
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<sourceDirectory>src/main/java</sourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<!--该模块中的resources中的配置文件是否需要打包入jar文件中-->
<includes>
<include>**/*.*</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<resource>
<directory>src/main/views</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<!-- 排除一些过滤的文件,由于编译会更改相关文件内容,导致文件不可用,如www.chendd.cn.pfx -->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>pfx</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
<!-- 设置程序启动的Main Class -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<!--打包时排除jar中的资源文件-->
<executions>
<execution>
<phase>package</phase>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix></classpathPrefix>
<mainClass>cn.chendd.Bootstrap</mainClass>
</manifest>
</archive>
<excludes>
<exclude>/application*.yaml</exclude>
<exclude>/config/**</exclude>
<exclude>/prod/**</exclude>
<exclude>/test/**</exclude>
<exclude>**/*.java</exclude>
</excludes>
</configuration>
</plugin>
<!-- 打包插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<!-- 配置执行器 -->
<execution>
<id>assembly-admin</id>
<!-- 绑定到package生命周期阶段上 -->
<phase>package</phase>
<goals>
<!-- 只运行一次,会生拷贝响应的文件至输出目录 -->
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<!--打包文件夹目录名称,默认格式为artifactId-version-->
<finalName>chendd</finalName>
<descriptors>
<!--assembly配置文件路径-->
<descriptor>src/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
<!-- 打包环境参数 -->
<profiles>
<profile>
<id>dev</id>
<!-- 默认打包采取的模式 -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<filters.envFolder>src/main/resources</filters.envFolder>
<filters.envName></filters.envName>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<filters.envFolder>src/main/resources/test</filters.envFolder>
<filters.envName>-test</filters.envName>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<filters.envFolder>src/main/resources/prod</filters.envFolder>
<filters.envName>-prod</filters.envName>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
</profiles>
admin模块assembly.xml
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<!--
apache plugin项目地址:https://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
<id>此程序集的id<id>
<format>常见的打包文件格式:zip、tar、tar.gz、jar、dir、war等</format>
<includeBaseDirectory>在最终存档中包含一个基本目录</includeBaseDirectory>
-->
<!--生成的根文件夹名称为:pom.xml中finalName定义的前缀 + '-' + 此处的id-->
<id>admin</id>
<formats>
<!--打包的文件格式,可以是:dir、war、zip、tar.gz-->
<format>dir</format>
</formats>
<!--是否在target目录下创建一个根文件夹,取名baseDirectory-->
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>admin-all</baseDirectory>
<!--指定要包含在程序集中的文件组-->
<fileSets>
<fileSet>
<directory>src/bin</directory>
<directoryMode>0755</directoryMode>
<fileMode>0777</fileMode>
<outputDirectory>bin</outputDirectory>
<lineEnding>unix</lineEnding>
</fileSet>
<fileSet>
<directory>${filters.envFolder}</directory>
<excludes>
<!--根据环境设置排除的目录,若打包为test环境时排除src/main/resources/test/test/**路径-->
<exclude>test/**</exclude>
<exclude>prod/**</exclude>
<!--此文件由下方特殊处理-->
<exclude>application${filters.envName}.yaml</exclude>
</excludes>
<outputDirectory>conf</outputDirectory>
</fileSet>
</fileSets>
<!--创建文件夹以及重命名资源文件-->
<files>
<!-- 重命名资源文件名称,但当文件不存在时报错了,使用copy-rename-maven-plugin插件解决 -->
<file>
<source>${filters.envFolder}/application${filters.envName}.yaml</source>
<outputDirectory>conf</outputDirectory>
<destName>application.yaml</destName>
<filtered>true</filtered>
</file>
<!--创建runtime文件夹用于启动命令时指定临时目录-Djava.io.tmpdir-->
<file>
<source></source>
<outputDirectory>runtime</outputDirectory>
</file>
<!--创建logs文件夹用于输出日志文件时的根目录-->
<file>
<source></source>
<outputDirectory>logs</outputDirectory>
</file>
</files>
<!--项目依赖的jar配置-->
<dependencySets>
<dependencySet>
<useProjectArtifact>true</useProjectArtifact>
<outputDirectory>lib-jar</outputDirectory>
<!--是否解压缩jar文件-->
<unpack>false</unpack>
<!--依赖jar文件的范围-->
<scope>runtime</scope>
<!--排除项目内的jar-->
<excludes>
<exclude>cn.chendd*:*</exclude>
</excludes>
</dependencySet>
<dependencySet>
<useProjectArtifact>true</useProjectArtifact>
<outputDirectory>lib-local</outputDirectory>
<unpack>false</unpack>
<!--将使用SystemPath依赖的本地jar拷贝至同级目录-->
<scope>system</scope>
<!--排除项目内的jar-->
<excludes>
<exclude>cn.chendd*:*</exclude>
</excludes>
</dependencySet>
<dependencySet>
<useProjectArtifact>true</useProjectArtifact>
<outputDirectory>lib-project</outputDirectory>
<unpack>false</unpack>
<includes>
<include>cn.chendd*:*</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>
源码工程下载:源码下载.zip;
点赞