SpringBoot 配置文件与依赖库分离打包配置

Stella981
• 阅读 540

一、应用场景

一般情况下我们对springboot应用打包时使用springboot的maven插件spring-boot-maven-plugin的maven进行打包,打包完成得到一个fatjar,fatjar的优点是可以直接运行,缺点是体积太大,不利于传输,springboot应用打出来的fatjar体积少则几十M,多则上百M,在往服务器部署传输时十分便,可能只改了某个类文件,都需要重新将整个fatjar重新传输一次,特别是走公网传输的时候,可能上传速度只有几百甚至几十KB,而整个fatjar中真正我们项目的代码文件可能也就几百KB或几兆的大小,所以有必要将fatjar中的依赖库与我们项目的class进行分离打包,这样每次更换项目class就方便很多,而将配置文件也分离出来的原因在于我们可能经常需要更改配置文件的内容,如果放在fatjar中这样修改是非常不方便的,所以也需要将配置文件也分离出来。

  fatjar 即将项目需要的所有依赖库及配置文件等打进一个jar或war,该文件可直接运行

二、配置

2.1 POM配置

下面对pom.xml进行配置,来实现分离打包,配置如下

4.0.0

<groupId>chenyb</groupId>
<artifactId>demo</artifactId>
<version>v1.2-release</version>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- springboot 打包插件 -->
        <!--
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>com.xx.xx</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        -->

        <!-- maven 打包插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <!-- MANIFEST.MF 中 Class-Path 加入前缀 -->
                        <classpathPrefix>lib/</classpathPrefix>
                        <!-- jar包不包含唯一版本标识 -->
                        <useUniqueVersions>false</useUniqueVersions>
                        <!-- 指定入口类 -->
                        <mainClass>cn.test.DemoApplication</mainClass>
                    </manifest>
                </archive>
                <outputDirectory>${project.build.directory}</outputDirectory>
            </configuration>
        </plugin>

        <!-- 拷贝依赖 -->
        <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>
                        <overWriteReleases>true</overWriteReleases>
                        <overWriteSnapshots>true</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>

关键配置说明:

(1) 去掉了spring-boot-maven-plugin打包插件

(2) 添加 maven-jar-plugin (maven标准打包插件)

(3) maven-dependency-plugin(依赖拷贝插件,主要用于将maven依赖库拷贝出来)

插件具体的配置,pom.xml中已添加备注说明

2.2 打包

执行maven package 命令进行打包,得到的结果如下

SpringBoot 配置文件与依赖库分离打包配置

 将 lib目录 及 项目jar 文件拷贝到同一目录下,我为了测试方便,先全部拷贝到桌面上,(放置服务器上时也需保证在同一目录下)

SpringBoot 配置文件与依赖库分离打包配置

 打开demo-v1.2-release可以看到,并没有将依赖jar打进来,大小只有不到4KB

SpringBoot 配置文件与依赖库分离打包配置 SpringBoot 配置文件与依赖库分离打包配置

2.3 config目录创建

以上做完还还需要将项目配置文件拷贝出来,在与jar包平级目录建立config目录,将项目中的application.properties或yaml文件拷贝进来

SpringBoot 配置文件与依赖库分离打包配置

  config 下的文件

SpringBoot 配置文件与依赖库分离打包配置

经过以上步骤,全部配置完毕,下面进行一下简单的测试

三、测试

 为了保证加载的是外部config目录的配置文件,我将application-test.yaml中的server.port改为8085, 打开命令行输入

C:\Users\Administrator\Desktop>java -jar -Dspring.profiles.active=dev -Dspring.location.config=config/ C:\Users\Administrator\Desktop\demo-v1.2-release.jar

回车运行,能正常启动说明外部依赖可以正常加载进来

SpringBoot 配置文件与依赖库分离打包配置

 可以看到启动完成后tomcat监听端口为8085,说明外部配置加载成功。

PS : 如果外部配置文件加载失败,会使用项目jar中的配置文件,如下图,也就是启动后会是8080端口

SpringBoot 配置文件与依赖库分离打包配置

SpringBoot 配置文件与依赖库分离打包配置

application-dev.yaml中配置的端口是8080

SpringBoot 配置文件与依赖库分离打包配置

而我已将外部config目录下application-dev.yaml中端口做了修改,使用外部配置文件启动后会是8085端口

SpringBoot 配置文件与依赖库分离打包配置

四、一点小坑

默认情况下window命令行打开后,是在当前用户目录下,像这样

SpringBoot 配置文件与依赖库分离打包配置

 而我的config、lib、项目jar拷贝在桌面上,实际路径是

SpringBoot 配置文件与依赖库分离打包配置

一开始我在  C:\Users\Administrator> 直接执行下方命令,一直加载不到配置文件

java -jar -Dspring.profiles.active=de'v -Dspring.location.config=config/ C:\Users\Administrator\Desktop\demo-v1.2-release.jar

原因就在于程序与配置文件不在同一目录下,我在C:\Users\Administrator>运行启动命令,而程序实际目录在 C:\Users\Administrator\Desktop> 下,因为程序使用了绝对路径,可以找到文件,所以程序的实际运行路径为C:\Users\Administrator\Desktop,而我使用的配置 spring.location.config=config/ 使用的是相对路径,,这个相对路径又是相对 C:\Users\Administrator> 目录,所以就会出现找不到配置文件的情况。

解决办法一:

命令行切换到 C:\Users\Administrator\Desktop 目录,即项目jar所在目录,运行 java -jar 命令

解决办法二:

将config拷贝到C:/Users/Administrator下,保证C:/Users/Administrator相对路径下存在config目录及配置文件(该方法可解决问题,但是不建议)

解决方法三:

spring.location.config=config/ 处使用绝对路径,即C:/Users/Administrator/Desktop/config/ 

所以很重要一点,一定保证 执行命令 的目录 与项目jar、lib、config都在同一目录下。

五、完整demo地址

https://github.com/yuboon/java-examples/tree/master/springboot-package-segment

点赞
收藏
评论区
推荐文章
秃头王路飞 秃头王路飞
4个月前
webpack5手撸vue2脚手架
webpack5手撸vue相信工作个12年的小伙伴们在面试的时候多多少少怕被问到关于webpack方面的知识,本菜鸟最近闲来无事,就尝试了手撸了下vue2的脚手架,第一次发帖实在是没有经验,望海涵。languageJavaScript"name":"vuecliversion2","version":"1.0.0","desc
技术小男生 技术小男生
4个月前
linux环境jdk环境变量配置
1:编辑系统配置文件vi/etc/profile2:按字母键i进入编辑模式,在最底部添加内容:JAVAHOME/opt/jdk1.8.0152CLASSPATH.:$JAVAHOME/lib/dt.jar:$JAVAHOME/lib/tools.jarPATH$JAVAHOME/bin:$PATH3:生效配置
光头强的博客 光头强的博客
4个月前
Java面向对象试题
1、请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
刚刚好 刚刚好
4个月前
css问题
1、在IOS中图片不显示(给图片加了圆角或者img没有父级)<div<imgsrc""/</divdiv{width:20px;height:20px;borderradius:20px;overflow:h
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
小森森 小森森
4个月前
校园表白墙微信小程序V1.0 SayLove -基于微信云开发-一键快速搭建,开箱即用
后续会继续更新,敬请期待2.0全新版本欢迎添加左边的微信一起探讨!项目地址:(https://www.aliyun.com/activity/daily/bestoffer?userCodesskuuw5n)\2.Bug修复更新日历2.情侣脸功能大家不要使用了,现在阿里云的接口已经要收费了(土豪请随意),\\和注意
晴空闲云 晴空闲云
4个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
3个月前
快速入门|使用MemFire Cloud构建React Native应用程序
MemFireCloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Stella981 Stella981
1年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
helloworld_28799839 helloworld_28799839
4个月前
常用知识整理
Javascript判断对象是否为空jsObject.keys(myObject).length0经常使用的三元运算我们经常遇到处理表格列状态字段如status的时候可以用到vue