一,前言
SpringBoot应用常规部署方式是将其打成一个可执行jar包,使其能够通过java -jar xxx.jar命令方式进行启动,因此需要使用Maven等工具进行打包。
二,Maven打包
Springboot应用最简单打包方式:在pom.xml文件中添加相应的打包插件,具体代码如下:
1 <build> 2 <plugins> 3 <plugin> 4 <groupId>org.springframework.boot</groupId> 5 <artifactId>spring-boot-maven-plugin</artifactId> 6 <configuration> 7 <fork>true</fork> 8 </configuration> 9 </plugin> 10 </plugins> 11 </build>
这样打包出来的jar文件比较大,包含了依赖包,以及配置文件等等,然而在实际使用过程中,我们发现那些依赖的jar包是很少会变动的,而且这部分文件也比较大,所以我们最好是可以将可执行的jar包和这些依赖jar包分开;另外,对于一些静态的配置文件,如.proterties,.xml,*.yml等文件,有的时候需要在不重新发布的情况下进行修改,这样,我们也可以将这些配置文件也和可执行jar文件分开。于是我们可以将最终打出来的包分为三个部分:可执行jar文件;依赖jar包文件;配置文件,我们将依赖jar包放入lib文件夹下面,配置文件放入config文件夹下面,最后将这三部分文件打成一个zip包,然后放到对应服务器上解压后运行,下面我们来看看具体配置。
1.指定java编译插件
1 <plugin> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-compiler-plugin</artifactId> 4 <configuration> 5 <source>1.8</source> 6 <target>1.8</target> 7 <encoding>UTF-8</encoding> 8 </configuration> 9 </plugin>
指定java版本以及编码格式。
2.可执行jar文件打包
1 <plugin> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-jar-plugin</artifactId> 4 <configuration> 5 <archive> 6 <manifest> 7 <addClasspath>true</addClasspath> 8 <classpathPrefix>lib</classpathPrefix> 9 <!-- 程序启动入口 --> 10 <mainClass>com.wf.blog.Application</mainClass> 11 </manifest> 12 <manifestEntries> 13 <Class-Path>./</Class-Path> 14 </manifestEntries> 15 </archive> 16 </configuration> 17 <executions> 18 <execution> 19 <phase>prepare-package</phase> 20 <goals> 21 <goal>jar</goal> 22 </goals> 23 <configuration> 24 <excludes> 25 <exclude>mybatisGenerator/**</exclude> 26 <exclude>config/**</exclude> 27 <exclude>*.properties</exclude> 28 </excludes> 29 </configuration> 30 </execution> 31 </executions> 32 </plugin>
这里需要指定程序启动入口类,<Class-Path>./</Class-Path>
表示将jar文件所在目录设置成claspath路径;在进行可执行jar文件打包的时候需要将一些不需要的文件排除在外,如一些和运行无关的,以及一些分离的配置,通过<excludes>
进行处理,这样打出来的jar包就只包含本应用的基本内容,class文件以及一些必须打进jar包的配置文件。
三,assembly插件打包
最后需要将配置文件依赖jar包以及上面打出来的可执行jar文件一起打包成zip文件,这里需要使用到maven的assembly插件,新建src/main/build文件夹,并新建一个package.xml文件,具体打包实现在这个文件里面做的,在pom.xml文件我们需要将其指定到此文件:
1 <plugin> 2 <artifactId>maven-assembly-plugin</artifactId> 3 <configuration> 4 <!-- not append assembly id in release file name --> 5 <appendAssemblyId>false</appendAssemblyId> 6 <descriptors> 7 <!-- 注意这里的路径 --> 8 <descriptor>src/main/build/package.xml</descriptor> 9 </descriptors> 10 </configuration> 11 <executions> 12 <execution> 13 <id>make-assembly</id> 14 <phase>package</phase> 15 <goals> 16 <goal>single</goal> 17 </goals> 18 </execution> 19 </executions> 20 </plugin>
package.xml具体实现如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> 4 <id>package</id> 5 <formats> 6 <format>zip</format> 7 </formats> 8 <!-- 改为false不会出现两层相同的目录 --> 9 <includeBaseDirectory>false</includeBaseDirectory> 10 <fileSets> 11 <fileSet> 12 <directory>target/classes</directory> 13 <outputDirectory>config</outputDirectory> 14 <includes> 15 <include>*.properties</include> 16 </includes> 17 <excludes> 18 <exclude>mybatisGenerator/**</exclude> 19 </excludes> 20 <fileMode>0640</fileMode> 21 </fileSet> 22 <fileSet> 23 <directory>target/classes/config</directory> 24 <outputDirectory>config</outputDirectory> 25 <includes> 26 <include>*.properties</include> 27 <include>*.xml</include> 28 <include>*.yml</include> 29 </includes> 30 <fileMode>0640</fileMode> 31 </fileSet> 32 <fileSet> 33 <directory>${project.build.directory}</directory> 34 <outputDirectory>${file.separator}</outputDirectory> 35 <includes> 36 <include>*.jar</include> 37 </includes> 38 </fileSet> 39 </fileSets> 40 <dependencySets> 41 <dependencySet> 42 <outputDirectory>lib</outputDirectory> 43 <scope>runtime</scope> 44 <!--<unpack>false</unpack> --> 45 <excludes> 46 <!--<exclude>${project.name}-${project.version}</exclude> --> 47 <exclude>${groupId}:${artifactId}</exclude> 48 </excludes> 49 </dependencySet> 50 </dependencySets> 51 </assembly>
可以看到将target/classes中的文件进行了区分处理,对明确需要和执行jar文件分开的都放入到config文件夹,另外,依赖包也放入了lib文件夹。
最终目录结构如下图所示:
四,应用无限重启问题
由于Springboot应用可以开启热部署功能,当发现classpath目录下面文件有变更的时候就会自动重新启动应用,而我们应用日志文件正好是在classpath的logs目录下面的,所以发现日志文件有变化也会重新启动,因此才会出现无限重启现象。解决办法有两种:
- 1.将日志的目录移除classpath路径下。
- 2.在springboot配置文件中的热部署配置中排除检测目录。
第二种方式具体配置如下:
1 spring: 2 devtools: 3 restart: 4 enabled: true 5 additional-exclude: logs/**