关于Springboot 应配置外移和Maven个性化打包一些做法

news/2025/3/10 17:53:08/

期望达到的效果是每次更新服务器端应用只需要更新主程序jar 依赖jar单独分离。配置文件独立存放于文件夹内,更新程序并不会覆盖已有的配置信息。

一、配置外移

1、开发环境外移

做法:在项目同级或者上级创建config文件夹放置配置文件,具体module内部application.properties通过spring.profiles.include引用外部配置。利用的是springboot加载配置顺序原理,优先同级config文件夹,然后是同级properties,继而是jar包内部的properties。

在这里插入图片描述
但是如果是用test测试用例则无法配置外移需要将配置放于test/resources
在这里插入图片描述
这里附带一下springboot 测试用例写法

import com.health.AdminSrvApp;
import com.health.bean.po.UserInfo;
import com.health.main.service.UserInfoService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;import javax.annotation.Resource;/*** @author katasea* 2020/7/14 10:27*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AdminSrvApp.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource("classpath:application.yml")
@Slf4j
public class UserInfoServiceTest {@ResourceUserInfoService userInfoService;@Testpublic void testSaveOrUpdate(){log.info("无法获取登录用户信息,模拟返回用户:test,2,test 要修改检索:LoginHandlerMethodArgumentResolver.java");UserInfo userInfo = new UserInfo();userInfo.setUserId("test");userInfo.setUserType(2);userInfo.setUserName("test2");userInfo.setIsAdmin(1);userInfo.setPhone(18650093759L);userInfo.setSex(1);userInfoService.mySaveOrUpdate(userInfo);}
}

也顺便附带一下logback配置文件内容

<?xml version="1.0" encoding="UTF-8"?>
<configuration><contextName>admin-srv</contextName><property name="LOG_PATH" value="log" /><!--<property name="CONSOLE_LOG_PATTERN"--><!--value="%boldRed(%date{yyyy-MM-dd HH:mm:ss}) | %boldYellow(%thread) | %msg%n"/>--><!-- 日志记录器,日期滚动记录 --><appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${LOG_PATH}/admin-srv_log_error.log</file><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 --><fileNamePattern>${LOG_PATH}/error/admin-srv_log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern><!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,命名日志文件,例如log-error-2013-12-21.0.log --><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>10MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><!-- 追加方式记录日志 --><append>true</append><!-- 日志文件的格式 --><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | MDC[%X{requestId}] | %logger :%-3L| %msg%n</pattern><!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>--><charset>utf-8</charset></encoder><!-- 此日志文件只记录info级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>error</level><!--<onMatch>ACCEPT</onMatch>--><!--<onMismatch>DENY</onMismatch>--></filter></appender><!-- 日志记录器,日期滚动记录 --><appender name="FILEDEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${LOG_PATH}/admin-srv_log_debug.log</file><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_PATH}/info/admin-srv_log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>10MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><!-- 追加方式记录日志 --><append>true</append><!-- 日志文件的格式 --><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | MDC[%X{requestId}] | %logger | %msg%n</pattern><charset>utf-8</charset></encoder><!-- 此日志文件只记录debug级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>debug</level><!--<onMatch>ACCEPT</onMatch>--><!--<onMismatch>DENY</onMismatch>--></filter></appender><appender name="ASYNC_FILEDEBUG" class="ch.qos.logback.classic.AsyncAppender"><!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --><discardingThreshold>0</discardingThreshold><!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --><queueSize>10000</queueSize><!-- 添加附加的appender,最多只能添加一个 --><appender-ref ref="FILEDEBUG"/></appender><appender name="ASYNC_FILEERROR" class="ch.qos.logback.classic.AsyncAppender"><!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --><discardingThreshold>0</discardingThreshold><!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --><queueSize>10000</queueSize><!-- 添加附加的appender,最多只能添加一个 --><appender-ref ref="FILEERROR"/></appender><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><!--encoder 默认配置为PatternLayoutEncoder--><encoder><!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | MDC[%X{requestId}] | %msg%n</pattern><!--<pattern>${CONSOLE_LOG_PATTERN}</pattern>--><!--<charset>gbk</charset>--></encoder><!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>debug</level></filter></appender><logger name="org.springframework" level="WARN" /><logger name="com.health.main.mapper" level="DEBUG" /><!-- 生产环境下,将此级别配置为适合的级别,以免日志文件太多或影响程序性能 --><root level="INFO"><appender-ref ref="ASYNC_FILEERROR" /><!--<appender-ref ref="FILEWARN" />--><appender-ref ref="ASYNC_FILEDEBUG" /><!-- 生产环境将请stdout,testfile去掉 --><appender-ref ref="STDOUT" /></root>
</configuration>
2、生产环境部署分离

这里按开发环境一样将配置文件放config文件夹与module同级,并在同级下编写启动脚本。
在这里插入图片描述
文件夹内部如下图则是lib与主jar分离的形式。具体maven如何编写下面会介绍。
在这里插入图片描述
这里附带脚本写法

title 应用名称:8503/dubbo:20890
java -Xmx256M -Xms256M -jar -Dfile.encoding=gbk -Dloader.path=./admin-srv/lib,./config  ./admin-srv/admin-srv-v1.0.jar.original

配置文件夹需要与启动脚本同级,这里脚本加了限制启动内存,jar包路径等根据实际情况自己修改。

二、MAVEN打包

1、普通lib包分离

maven关键配置如下:

<build><resources><resource><directory>src/main/resources</directory><includes><include>**/*</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/*.xml</include></includes></resource><resource><directory>src/main/resources/mapping/*</directory><includes><include>**/*.xml</include></includes></resource></resources><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><configuration><!-- jdk 版本和编译等级 --><source>${java.version}</source><target>${java.version}</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><!--这里如果是true 打包的jar 无法用rar重新放入class文件--><excludeDevtools>false</excludeDevtools></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.4</version><configuration><archive><!--不打包依赖的jar,把依赖的jar copy到lib目录,和生成的jar放在同一级目录下--><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><mainClass>com.health.AdminSrvApp</mainClass></manifest></archive><alias>abc</alias></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy-dependencies</id><phase>prepare-package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>target/lib</outputDirectory><overWriteReleases>false</overWriteReleases><overWriteSnapshots>false</overWriteSnapshots><overWriteIfNewer>true</overWriteIfNewer></configuration></execution></executions></plugin> </plugins></build>

直接用maven打包命令即可: mvn package -Dmaven.test.skip=true
打包后目录如下,拷贝lib文件夹和original轻量包到上面生产环境的具体服务文件夹下即可。
在这里插入图片描述

2、自定义某些lib包不分离合并到主jar一起打包

实际中,我们需要频繁拷贝 api common 等jar来更新各个文件夹内部的lib对应的jar十分繁琐,有没有可能将经常变动的jar也合并打包到轻量包内,不经常变动的外部引用jar才放置于lib文件夹呢?这样后续更新只要更新original轻量包重新启动脚本即可。无需每次更新都拷贝大量的不变的lib文件夹外部的jar。

为了实现自定义打包则需要使用maven另外一个插件 maven部分代码如下。

<build><resources><resource><directory>src/main/resources</directory><includes><include>**/*</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/*.xml</include></includes></resource><resource><directory>src/main/resources/mapping/*</directory><includes><include>**/*.xml</include></includes></resource></resources><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><configuration><!-- jdk 版本和编译等级 --><source>${java.version}</source><target>${java.version}</target><encoding>UTF-8</encoding></configuration></plugin><!--            <plugin>--><!--                <groupId>org.springframework.boot</groupId>--><!--                <artifactId>spring-boot-maven-plugin</artifactId>--><!--                <configuration>--><!--                    <excludeDevtools>false</excludeDevtools>--><!--                </configuration>--><!--            </plugin>--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.4</version><configuration><archive><!--不打包依赖的jar,把依赖的jar copy到lib目录,和生成的jar放在同一级目录下--><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><mainClass>com.health.AdminSrvApp</mainClass></manifest></archive><alias>abc</alias></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy-dependencies</id><phase>prepare-package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>target/lib</outputDirectory><overWriteReleases>false</overWriteReleases><overWriteSnapshots>false</overWriteSnapshots><overWriteIfNewer>true</overWriteIfNewer></configuration></execution></executions></plugin><!-- 这里来实现自定义的maven打包 可以指定哪些jar要合并到original --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-antrun-plugin</artifactId><version>1.8</version><executions><execution><phase>package</phase><goals><goal>run</goal></goals><configuration><target><echo>Building 描述信息 START....</echo><!-- 删除目录 --><delete dir="target/temp"/><!-- 删除目录 --><mkdir dir="target/temp"/><mkdir dir="target/temp/main"/><mkdir dir="target/temp/oth"/><!-- 复制目录文件 复制到-todir 要复制的目录-fileset --><echo>Copying jar START....</echo><!--                                <copy tofile="target/${project.artifactId}-${project.version}.jar.original"-->
<!--                                      file="target/${project.artifactId}-${project.version}.jar"-->
<!--                                      failonerror="false" verbose="true" overwrite="true">-->
<!--                                </copy>--><!--个性化制作jar包 --><!-- 第一步 先把常用的jar挪到dir中 --><copy todir="target/temp/oth"failonerror="false" verbose="true" overwrite="true"><!-- TODO 以下就是要合并到original的jar 根据自己情况编辑 还包括下面一段内容 --><fileset dir="target/lib" includes="mall-*.jar"/><fileset dir="target/lib" includes="core-srv-*.jar"/></copy><copy tofile="target/temp/main/${project.artifactId}-${project.version}.jar"file="target/${project.artifactId}-${project.version}.jar"failonerror="false" verbose="true" overwrite="true"></copy><!-- 第二步 删除lib里面的这些常用jar --><delete><!-- TODO 以下就是要合并到original的jar 根据自己情况编辑 应该与上面定义的拷贝内容一致! --><fileset dir="target/lib" includes="mall-*.jar"/><fileset dir="target/lib" includes="core-srv-*.jar"/></delete><!-- 第三步 解压临时文件夹的jar --><unzip dest="target/temp/oth"><fileset dir="target/temp/oth"></fileset></unzip><unzip dest="target/temp/main" overwrite="true"><fileset dir="target/temp/main"></fileset></unzip><!-- 第四步 删除temp里面的其他jar留下 主程序jar--><delete><fileset dir="target/temp/oth" includes="*.jar"/><fileset dir="target/temp/main" includes="*.jar"/></delete><!-- 第六步 删除temp里面的jar待会儿要压缩--><copy todir="target/temp"failonerror="false" verbose="true" overwrite="true"><fileset dir="target/temp/oth"/></copy><copy todir="target/temp"failonerror="false" verbose="true" overwrite="true"><fileset dir="target/temp/main"/></copy><delete dir="target/temp/oth"/><delete dir="target/temp/main"/><!--第七步 重新压缩一个jar --><!--                                <jar--><!--                                        jarfile="target/${project.artifactId}-${project.version}.jar.original2"--><!--                                        basedir="target/temp"--><!--                                >--><!--                                </jar>--><!--destfile	目标文件duplicate	打包方式(一般使用preserve)zipfileset	打包那些文件prefix		增加前缀(使用最佳实践)--><zip destfile="target/${project.artifactId}-${project.version}.jar.original"duplicate="preserve"><zipfileset dir="target/temp" includes="**/*.*" /></zip><echo>Building 描述信息 END</echo></target></configuration></execution></executions></plugin></plugins></build>

还是如上执行 mvn package -Dmaven.test.skip=true 打包命令
可以用rar打开 打包后的 original包,可以看到class文件已经合并打包到内部里了。


http://www.ppmy.cn/news/1578144.html

相关文章

Windows控制台函数:控制台读取输入函数ReadConsoleA()

目录 什么是 ReadConsoleA&#xff1f; 它长什么样&#xff1f; 怎么用它&#xff1f; 它跟 std::cin 有什么不一样&#xff1f; 注意事项 什么是 ReadConsoleA&#xff1f; ReadConsoleA 是一个 Windows API 函数&#xff0c;用来从控制台读取用户输入。想象一下&#…

Java进阶:Docker

1. Docker概述 1.1. Docker简介 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言开发。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱…

DR和BDR的选举规则

在 OSPF&#xff08;开放最短路径优先&#xff09;协议中&#xff0c;DR&#xff08;Designated Router&#xff0c;指定路由器&#xff09; 和 BDR&#xff08;Backup Designated Router&#xff0c;备份指定路由器&#xff09; 的选举是为了在广播型网络&#xff08;如以太网…

游戏引擎学习第146天

音高变化使得对齐读取变得不可能&#xff0c;我们可以支持循环声音了。 我们今天的目标是完成之前一段时间所做的音频代码。这个项目并不依赖任何引擎或库&#xff0c;而是一个教育项目&#xff0c;目的是展示从头到尾运行一个游戏所需要的全部代码。无论你对什么方面感兴趣&a…

pyqt实现yolov8主界面和登录界面以及数据库

1.界面展示 首先是通过QDesigner模仿设计的一个简洁的登录界面 然后是点击注册页面 最后就是集成YOLO的主界面了 2.界面跳转设计 主要是通过一个类来管理登录注册以及主界面, class main():def __init__(self):super(main, self)._

加油站小程序实战教程09显示站点信息

目录 引言1 搭建布局2 创建变量3 初始化站点4 点选站点时联动5 数据绑定最终效果完整代码总结 引言 在《加油站小程序实战教程08动态获取城市和站点信息》中&#xff0c;我们已经介绍了如何动态的读取城市及站点信息显示到地图上。站点信息读取到后&#xff0c;如果在地图点选…

FusionInsight MRS云原生数据湖

FusionInsight MRS云原生数据湖 1、FusionInsight MRS概述2、FusionInsight MRS解决方案3、FusionInsight MRS优势4、FusionInsight MRS功能 1、FusionInsight MRS概述 1.1、数据湖概述 数据湖是一个集中式存储库&#xff0c;允许以任意规模存储所有结构化和非结构化数据。可以…

elk的相关的基础

以下是关于ELK&#xff08;Elasticsearch, Logstash, Kibana&#xff09;的200个基础问题及其答案&#xff0c;涵盖了ELK的核心概念、组件、配置、使用场景、优化等方面。 ​Elasticsearch 基础 ​**什么是Elasticsearch&#xff1f;**​ 答&#xff1a;Elasticsearch是一个分…