SpringBoot分离打Jar包的两种配置方式
作者:SerikaOnoe 发布时间:2023-01-30 09:06:59
SpringBoot分离打Jar包的两种方式
方式一:基于maven-jar-plugin
此方式基于这个小伙伴的配置改的:https://www.jb51.net/article/188606.htm
注意
这种方式打包出来的Jar基于插件提供的类加载器启动:
org.springframework.boot.loader.PropertiesLauncher
所有依赖包(包括systemScope),会通过插件
maven-dependency-plugin
自动复制到lib
目录所有资源文件,会通过插件
maven-resources-plugin
自动复制到config
目录此方式打包后,需要指定参数启动
-Dloader.path=lib路径,config路径
打包完后部署需要的文件清单:(在
target/
目录下都可以看到)config/**
:所有resources下的资源文件lib/**
:所有lib包,包括本地依赖xxx.jar
:应用Jar运行:
java -Dloader.path=lib,config -Dspring.profiles.active=dev -jar main.jar
简略版配置
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<properties>
<!--依赖输出目录-->
<lib-path>lib</lib-path>
<!--配置文件输出目录-->
<config-path>config</config-path>
<!--jar包名称-->
<final-name>xxx</final-name>
<!--指定启动类-->
<main-class>org.jeecg.JeecgSystemApplication</main-class>
</properties>
<build>
<!--项目名称-->
<finalName>${final-name}</finalName>
<plugins>
<!--定义项目的编译环境-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!--maven的测试用例插件,建议跳过。-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<!--这个是springboot的默认编译插件,他默认会把所有的文件打包成一个jar-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<!-- 打自定义的JAR包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<!-- MANIFEST.MF 中 Class-Path 加入前缀 -->
<classpathPrefix>${lib-path}/</classpathPrefix>
<!-- jar包不包含唯一版本标识 -->
<useUniqueVersions>false</useUniqueVersions>
<!--指定入口类 -->
<mainClass>${main-class}</mainClass>
</manifest>
<manifestEntries>
<!--MANIFEST.MF 中 Class-Path 加入资源文件目录 -->
<!--本地依赖,多个需要使用空格隔开-->
<Class-Path>./${config-path}/ lib/zwdd-1.2.0.jar lib/spire-10.jar</Class-Path>
</manifestEntries>
</archive>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
<!-- 该插件的作用是用于复制依赖的jar包到指定的文件夹里 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${lib-path}/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- 该插件的作用是用于复制指定的文件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<!-- 复制配置文件 -->
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<!--复制资源文件到外部,注意这里先不做filtering处理,防止某些静态文件损坏-->
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
<!--仅针对yml配置文件filtering处理(占位符@@等)-->
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<includes>
<include>*.yml</include>
</includes>
</resource>
</resources>
<outputDirectory>${project.build.directory}/${config-path}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<!--包含java类路径下的资源文件(mybatis的xml等)-->
<resource>
<directory>src/main/java</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.json</include>
<include>**/*.ftl</include>
</includes>
</resource>
<!--排除jar包内的所有resources配置文件-->
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*</exclude>
</excludes>
</resource>
<!--注: 为了能在IDEA中跑起来,需要将所有yml配置文件打进jar包,filtering必须开启(处理占位符等操作)-->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*.yml</include>
</includes>
</resource>
</resources>
</build>
</project>
完整配置(带部分注释)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-parent</artifactId>
<version>2.4.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jeecg-boot-module-system</artifactId>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun Repository</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.spire</groupId>
<artifactId>spire</artifactId>
<version>10</version>
<scope>system</scope>
<systemPath>${project.basedir}/../lib/Spire.Doc.jar</systemPath>
</dependency>
<dependency>
<groupId>com.zwdd.api</groupId>
<artifactId>zwdd</artifactId>
<version>1.2.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../lib/zwdd-sdk-java-1.2.0.jar</systemPath>
</dependency>
</dependencies>
<properties>
<!--依赖输出目录-->
<lib-path>lib</lib-path>
<!--springboot默认打包输出目录-->
<jar-path>jar</jar-path>
<!--配置文件输出目录-->
<config-path>config</config-path>
<!--jar包名称-->
<final-name>xxx</final-name>
<!--指定启动类-->
<main-class>org.jeecg.JeecgSystemApplication</main-class>
</properties>
<build>
<!--项目名称-->
<finalName>${final-name}</finalName>
<plugins>
<!--定义项目的编译环境-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!--maven的测试用例插件,建议跳过。-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<!--这个是springboot的默认编译插件,他默认会把所有的文件打包成一个jar,注意这里打包出来不会包含systemScope的jar包,有需要的话得在最后的resources里配置-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<!--这里仅展示插件作用,直接跳过此插件-->
<skip>true</skip>
<mainClass>${main-class}</mainClass>
<fork>true</fork>
<addResources>true</addResources>
<!--指定激活的配置文件application-xxx.yml-->
<profiles>${profile.name}</profiles>
<outputDirectory>${project.build.directory}/${jar-path}</outputDirectory>
</configuration>
</plugin>
<!-- 打自定义的JAR包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<!-- 不打包资源文件(配置文件和依赖包分开),这里配置的资源排除,仅在*.xml这类文件通配符筛选生效,因此不在这里处理 -->
<excludes>
<!--这种文件方式匹配可以生效-->
<!--<exclude>*.yml</exclude>-->
<!--下面这种方式配置是无效的,见:https://stackoverflow.com/questions/4113697/in-maven-how-to-exclude-resources-from-the-generated-jar-->
<!--上述问题链接中有此描述:<exclude>src/test/resources/**</exclude> doesn't work. Exclude will be applied on jar final path and should be <exclude>*.properties</exclude>-->
<!--<exclude>src/main/resources/**</exclude>-->
</excludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<!-- MANIFEST.MF 中 Class-Path 加入前缀 -->
<classpathPrefix>${lib-path}/</classpathPrefix>
<!-- jar包不包含唯一版本标识 -->
<useUniqueVersions>false</useUniqueVersions>
<!--指定入口类 -->
<mainClass>${main-class}</mainClass>
</manifest>
<manifestEntries>
<!--MANIFEST.MF 中 Class-Path 加入资源文件目录 -->
<!--本地依赖,多个需要使用空格隔开-->
<Class-Path>./${config-path}/ lib/zwdd-1.2.0.jar lib/spire-10.jar</Class-Path>
</manifestEntries>
</archive>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
<!-- 该插件的作用是用于复制依赖的jar包到指定的文件夹里 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!--这里可以手动添加构建id,但默认是全打包就不需要了-->
<!--<includeArtifactIds>xxxx</includeArtifactIds>-->
<!--默认包含所有scope,因此本地的依赖也正常复制-->
<!--<includeScope>system</includeScope>-->
<outputDirectory>${project.build.directory}/${lib-path}/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- 该插件的作用是用于复制指定的文件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<!-- 复制配置文件 -->
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<!--复制资源文件到外部,注意这里先不做filtering处理,防止某些静态文件损坏-->
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<includes>
<!--<include>*.yml</include>-->
<!--把所有resources目录下的资源文件复制出来-->
<include>**/*</include>
</includes>
</resource>
<!--仅针对yml配置文件filtering处理(占位符@@等)-->
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<includes>
<include>*.yml</include>
</includes>
</resource>
</resources>
<outputDirectory>${project.build.directory}/${config-path}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<!--手动处理资源文件,这里的操作都是针对最终打出的jar包内部文件的进行引入、筛选、过滤等等,默认文件都打进jar包内部的根路径下,因此前面的插件[maven-jar-plugin]中需要配置相对路径-->
<!--具体路径在这里: /project/build/plugins/[maven-jar-plugin]/configuration/archive/manifestEntries/Class-Path 添加classpath:. (注意和其它配置以空格分开)-->
<resources>
<!--包含java类路径下的资源文件(mybatis的xml等)-->
<resource>
<directory>src/main/java</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.json</include>
<include>**/*.ftl</include>
</includes>
</resource>
<!--排除jar包内的所有resources配置文件-->
<resource>
<directory>src/main/resources</directory>
<!--filtering会做处理配置文件@@占位符等操作,但是不排除某些文件的话可能导致压缩损坏-->
<filtering>false</filtering>
<excludes>
<exclude>**/*</exclude>
</excludes>
</resource>
<!--注: 上述配置已经能够正常分离所有配置、外部依赖、工程代码,启动命令:java -jar xxx.jar-->
<!--注: 但是工程打包后,你会发现IDEA上跑不起来(target/classes目录下没有配置文件)-->
<!--注: 这里尝试过在IDEA启动app时指定JVM参数(但是没有用,谁研究过可以说下): -Dloader.path=lib,config-->
<!--注: 为了能在IDEA中跑起来,需要将所有yml配置文件打进jar包,filtering必须开启(处理占位符等操作)-->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*.yml</include>
</includes>
</resource>
<!--本地依赖打进jar包,这个配置是配合spring-boot-maven-plugin插件使用的-->
<!--<resource>-->
<!--<directory>../lib/crack</directory>-->
<!--<targetPath>BOOT-INF/lib/</targetPath>-->
<!--<includes><include>**/*.jar</include></includes>-->
<!--</resource>-->
<!--<resource>-->
<!--<directory>../lib</directory>-->
<!--<targetPath>BOOT-INF/lib/</targetPath>-->
<!--<includes><include>*.jar</include></includes>-->
<!--</resource>-->
</resources>
</build>
</project>
方式二:基于spring-boot-maven-plugin
注意
这种方式打包出来的Jar基于插件提供的类加载器启动:
org.springframework.boot.loader.PropertiesLauncher
所有依赖包(包括systemScope),会通过插件
maven-dependency-plugin
自动复制到lib
目录所有资源文件,会通过插件
maven-resources-plugin
自动复制到config
目录此方式打包后,需要指定参数启动
-Dloader.path=lib路径,config路径
打包完后部署需要的文件清单:(在
target/
目录下都可以看到)config/**
:所有resources下的资源文件lib/**
:所有lib包,包括本地依赖xxx.jar
:应用Jar运行:
java -Dloader.path=lib,config -Dspring.profiles.active=dev -jar main.jar
配置参考
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
<finalName>main</finalName>
<plugins>
<!--该插件的作用是指定编译配置、做预处理,如Lombok、mapstruct等框架需要预处理代码-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.1.Final</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<!--该插件的作用是打包spring-boot的jar包-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--入口其实会自动配置-->
<mainClass>org.jeecg.JeecgSystemApplication</mainClass>
<!--不排除的话,systemScope的依赖包会自动被此插件打包进xxx.jar\BOOT-INF\lib,和外部依赖产生冲突 -->
<includeSystemScope>false</includeSystemScope>
<skip>false</skip>
<!--分离Jar包-->
<layout>ZIP</layout>
<includes>
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 该插件的作用是复制依赖的jar包到指定的文件夹里 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- 该插件的作用是复制指定的文件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<!-- 复制配置文件 -->
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<!--复制资源文件到外部,注意这里先不做filtering处理,防止某些静态文件损坏-->
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
<!--仅针对配置文件filtering处理(占位符@@等)-->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*.xml</include>
<include>*.yml</include>
<include>*.properties</include>
</includes>
</resource>
</resources>
<outputDirectory>${project.build.directory}/config</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<!--打包java路径下的静态文件-->
<resource>
<directory>src/main/java</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.json</include>
<include>**/*.ftl</include>
</includes>
</resource>
<!--注: 为了能在IDEA中跑起来,需要将所有yml配置文件打进jar包,filtering必须开启(处理占位符等操作)-->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*.yml</include>
<include>*.txt</include>
</includes>
</resource>
</resources>
</build>
</project>
附录:参考链接
SpringBoot项目分离打包
maven-jar-plugin插件对scope="system"依赖的处理
https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/
https://www.kancloud.cn/zhangdaiscott/jeecg-boot/3043463
Springboot jar包外指定配置文件及原理
Spring Boot之application.properites的failed to convert java.lang.String to java.lang.Integer问题解决
Maven maven-dependency-plugin包含本地依赖包
Spring Boot 分离资源文件打包
https://blog.csdn.net/weixin_40461281/article/details/115905734
https://www.jianshu.com/p/0277b6a17892
来源:https://blog.csdn.net/SerikaOnoe/article/details/128002977
猜你喜欢
- 茫茫人海千千万万,感谢这一秒你看到这里。希望我的面试题系列能对你的有所帮助!共勉!愿你在未来的日子,保持热爱,奔赴山海!Java基础知识(继
- 基于Java swing+MySQL实现学生信息管理系统:主要实现JDBC对学生信息进行增删改查,应付一般课设足矣,分享给大家。(由于篇幅原
- 此方案适用于解决springboot项目运行时动态添加数据源,非静态切换多数据源!!!一、多数据源应用场景:1.配置文件配置多数据源,如默认
- 上一次接触到编码的知识,还是上大学的时候,那时候学的是通信工程专业,有关编码的内容,不记得是在通信原理还是信息论与编码里面学到的了。却依然记
- 假如是在同一台机器上开发,前后端分离的工程中出现跨域问题的原因是,前端工程和后端工程运行在不同的端口上。只要协议、域名、端口有一个不同就会产
- 以下摘自胖哥分享的 2022开工福利教程。在学习Spring Security的时候你有没有下面这两个疑问:Spring Security的
- 前言当用户向服务器发送了一次HTTP请求,该请求可能会经过多个信息资源处理以后才返回给用户,各个信息资源使用请求转发机制相互转发请求,但是用
- 众所周知Java中的数据类型是强数据类型,基本数据类型之间的转换尤其固定的规则,当数据宽度比较窄的数据类型(如int)转换成数据类型比较宽的
- 一、概述现在大多数的电商APP的详情页长得几乎都差不多,几乎都是上面一个商品的图片,当你滑动的时候,会有Tab悬浮在上面,这样做用户体验确实
- 为了让我提供的通用 Mapper 的 boot-starter 同时兼容 Spring Boot 1.x 和 2.x,增加了这么一个工具类。
- 前端页面功能模块化拆分当一个系统的功能很多时,不可能所有功能模块的页面都写在一个页面里面,这时就需要将不同功能模块的页面拆分出去,就像模板一
- 面试中可能会被问到为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?Java 创建线程的方法实际
- 使用场景EntityListeners在jpa中使用,如果你是mybatis是不可以用的它的意义对实体属性变化的跟踪,它提供了保存前,保存后
- 在style中如下面那样定义:<style name="mystyle"> <item name=&
- 在C程序代码中我们可以利用操作系统提供的互斥锁来实现同步块的互斥访问及线程的阻塞及唤醒等工作。然而在Java中除了提供LockAPI外还在语
- 一、缩略图在浏览相册的时候,可能需要生成相应的缩略图。直接上代码:public class ImageUtil { private Logg
- springboot读取文件,打成jar包后访问不到最新开发出现一种情况,springboot打成jar包后读取不到文件,原因是打包之后,文
- 在android开发中,有时候我们想获取手机的一些硬件信息,比如android手机的总内存和可用内存大小。这个该如何实现呢?通过读取文件&q
- Spring Boot 的启动原理可以概括为以下几个步骤:加载 Spring Boot 应用程序的启动类根据启动类所在的包路径扫描相关的类根
- 一、引言在许多编程语言中,都有函数回调这一概念。C 和 C++ 中有函数指针,因此可以将函数作为参数传给其它函数,以便过后调用。而在 Jav