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

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

一、配置外移

1、开发环境外移

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

但是如果是用test测试用例则无法配置外移需要将配置放于test/resources

这里附带一下springboot 测试用例写法

java 复制代码
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 {
	@Resource
	UserInfoService userInfoService;
	@Test
	public 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 复制代码
<?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如何编写下面会介绍。

这里附带脚本写法

bash 复制代码
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关键配置如下:

xml 复制代码
<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部分代码如下。

xml 复制代码
<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文件已经合并打包到内部里了。

相关推荐
尘觉4 小时前
中秋节与 Spring Boot 的思考:一场开箱即用的团圆盛宴
java·spring boot·后端
小满、7 小时前
什么是Maven?关于 Maven 的坐标、依赖管理与 Web 项目构建
java·maven
半旧夜夏7 小时前
【设计模式】核心设计模式实战
java·spring boot·设计模式
皮皮林5517 小时前
SpringBoot 控制台秒变炫彩特效,秀翻同事指南!
spring boot
IT学长编程8 小时前
计算机毕设选题 基于SpringBoot的书店管理系统的设计与实现 网上书店系统 前后端分离 Java毕设项目 毕业设计选题 【附源码+文档报告+安装调试】
java·spring boot·毕业设计·课程设计·前后端分离·网上书店系统·书店管理系统
IT学长编程8 小时前
计算机毕设选题 基于SpringBoot的房产租赁管理系统 房屋租赁系统 前后端分离 Java毕设项目 毕业设计选题 【附源码+文档报告+安装调试】
java·spring boot·毕业设计·课程设计·房屋租赁系统·房产租赁系统·文档报告
李慕婉学姐9 小时前
【开题答辩过程】以《基于 Spring Boot 的宠物应急救援系统设计与实现》为例,不会开题答辩的可以进来看看
数据库·spring boot·宠物
yunmi_10 小时前
Spring Cloud Netfilx -- Ribbon:负载均衡工具(代码示例)
spring cloud·ribbon·maven·负载均衡
一只大头猿10 小时前
基于SpringBoot和Vue的超市管理系统
前端·vue.js·spring boot