背景

为实现快速搭建和开发,项目以Springboot框架搭建,springboot搭建的项目可以将项目直接打成jar包并运行,无需自己安装配置Tomcat或者其他服务器,是一种方便快捷的部署方式。

假设项目以最常规的方式打包成一个整体的jar包部署,即配置文件和第三方依赖包都包含在jar包里,就会有如下两个问题

问题一:项目运行过程中,要改动配置文件的话需要重新打包并部署。

问题二:多个第三方依赖包都相近的项目要部署在同一台服务器时,各自的jar包都包含了相同的第三方依赖包(假设项目jar包有100M,第三方依赖包可能就占用了99M),这样第三方依赖包冗余造成了服务器资源的浪费以及降低了项目部署的效率。

如果将各项目的配置文件、第三方依赖包都提取到jar包外统一管理,这样即提升了项目打包效率又节约了服务器的磁盘消耗,同时项目的运维也是非常方便的,改动了配置文件重启下服务就可以了,无需重新构建部署。

下面是具体的实现方案

1. 配置文件统一管理

1.1 springboot核心配置文件

Springboot读取核心配置文件(application.properties)的优先级为

Jar包同级目录的config目录

Jar包同级目录

classPath(即resources目录)的config目录

classpath目录

上面是springboot默认去拿自己的核心配置文件的优先级,还有一种最高优先级的方式是项目启动时通过命令的方式指定项目加载核心配置文件,命令如下

java –jar -Dspring.config.location=xxx/xxx/xxxx.properties xxxx.jar

如果Spring Boot在优先级更高的位置找到了配置,那么它会无视优先级更低的配置

1.2 其他资源配置文件

上面描述的Springboot核心文件已经能够提取出jar包外进行管理了,但是还有其他一些业务上的配置文件,如数据源配置文件,公共资源定义配置文件(常量,FTP信息等),quartz定时器,日志等配置文件我们如何去提取出来并确保能在代码中引用到呢

我们知道Springboot项目可以通过注解方式来获取相关配置文件,所以我们也是通过注解方式让项目能够引用到jar包外部的配置文件的,如下图:

@PropertySource里面的value有两个值,第一个是classpath下config目录下的数据源配置文件,第二个则是根据spring.profiles.path动态获取的目录,spring.profiles.path是我们在核心文件自定义的一个配置项,它的值是我们配置文件统一管理的文件夹路径,后面的ignoreResourceNotFound=true则是设定假如根据前面一个路径没有找到相关配置文件,则根据第二个路径去找。

我们还可以直接根据路径,用FileSystemResource类去加载一个配置文件实例出来,如下图

原理类似,根据在核心文件自定义的统一配置目录的路径来加载配置文件

另外logback日志配置文件加载方式如下:

综上所述,我们梳理一下实现方案的思路

1、        在springboot核心文件里定义一个spring.profiles.path配置项,它的值指向我们所有配置文件统一放置的目录,包含核心文件自身也是放置在里面的

2、        代码或者配置文件里加载配置文件的地方也应该获取spring.profiles.path配置项来动态加载该路径下的配置文件

3、        Pom.xml文件修改打包相关模块,将配置文件排除,这样我们打出的jar包是不含配置文件的,打包配置请参考文档节点3

4、        启动jar包时,通过命令指定加载的核心文件为spring.profiles.path下的核心文件

2. 第三方依赖包统一管理

通常第三方jar包可以打进jar包里,也可以放在项目jar包同级目录下的lib目录,我们可以根据修改pom.xml打包配置来实现,请参考文档节点3打包配置

3. 打包配置

<build>
                <resources>
                        <resource>
                                <directory>src/main/java</directory>
                                <includes>
                                        <include>**/*.properties</include>
                                        <include>**/*.xml</include>
                                </includes>
                                <filtering>true</filtering>
                        </resource>
                        <resource>
                                <directory>src/main/resources</directory>
                                <!—打包时排除配置文件-->
                                <excludes>
                                        <exclude>**/*.properties</exclude>
                                        <exclude>**/*.xml</exclude>
                                        <exclude>**/*.yml</exclude>
                                </excludes>
                                <filtering>false</filtering>
                        </resource>
                </resources>
                <plugins>
                        <plugin>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-compiler-plugin</artifactId>
                                <configuration>
                                        <source>1.8</source>
                                        <target>1.8</target>
                                        <fork>true</fork>
                                        <skip>true</skip>
                                        <executable>
                                                C:/Program Files/Java/jdk1.8.0_161/bin/javac.exe
                                        </executable>
                                </configuration>
                        </plugin>
                        <plugin>
                                <artifactId>maven-jar-plugin</artifactId>
                                <configuration>
                                        <archive>
                                                <manifest>
                                                        <addClasspath>true</addClasspath>
                                                        <classpathPrefix>lib/</classpathPrefix>
                                                        <useUniqueVersions>false</useUniqueVersions>
                                                        <mainClass>com.xrq.demo.Application</mainClass>
                                                </manifest>
                                                <manifestEntries>
                                                        <Class-Path>./</Class-Path>
                                                </manifestEntries>
                                        </archive>
                                        <excludes>
                                                <exclude>*.properties</exclude>
                                                <exclude>*.yml</exclude>
                                                <exclude>*.xml</exclude>
                                                <exclude>config/**</exclude>
                                        </excludes>
                                </configuration>
                        </plugin>
                        <plugin>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-dependency-plugin</artifactId>
                                <executions>
                                        <execution>
                                                <id>copy</id>
                                                <phase>package</phase>
                                                <goals>
                                                        <goal>copy-dependencies</goal>
                                                </goals>
                                                <configuration>
                                                        <outputDirectory>
                                                                ${project.build.directory}/lib
                                                        </outputDirectory>
                                                </configuration>
                                        </execution>
                                </executions>
                        </plugin>
                </plugins>
        </build>

改好pom.xml的build模块后,就可以通过mvn package 或者mvn install打出我们的jar包了

4. 项目管理shell脚本编写
自定义shell脚本,实现项目的启动,停止,状态,重启操作:

#!/bin/bash 
#这里可替换为你自己的执行程序,其他代码无需更改 
APP_NAME=demo1-0.0.1-SNAPSHOT.jar 
JVM="-server -Xms512m -Xmx512m -XX:PermSize=64M -XX:MaxNewSize=128m -XX:MaxPermSize=128m -Djava.awt.headless=true -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled"
APPFILE_PATH="-Dspring.config.location=/usr/local/demo/config/application-demo1.properties"
#使用说明,用来提示输入参数 
usage() { 
echo "Usage: sh 执行脚本.sh [start|stop|restart|status]" 
exit 1 

#检查程序是否在运行 
is_exist(){ 
pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' ` 
#如果不存在返回1,存在返回0 
if [ -z "${pid}" ]; then 
return 1 
else 
return 0 
fi 

#启动方法 
start(){ 
is_exist 
if [ $? -eq "0" ]; then 
echo "${APP_NAME} is already running. pid=${pid} ." 
else 
nohup java $JVM -jar $APPFILE_PATH $APP_NAME > /dev/null 2>&1 
fi

#停止方法 
stop(){ 
is_exist 
if [ $? -eq "0" ]; then 
kill -9 $pid 
else 
echo "${APP_NAME} is not running" 
fi 

#输出运行状态 
status(){ 
is_exist 
if [ $? -eq "0" ]; then 
echo "${APP_NAME} is running. Pid is ${pid}" 
else 
echo "${APP_NAME} is NOT running." 
fi 

#重启 
restart(){ 
stop 
start 

#根据输入参数,选择执行对应方法,不输入则执行使用说明 
case "$1" in 
"start") 
start 
;; 
"stop") 
stop 
;; 
"status") 
status 
;; 
"restart") 
restart 
;; 
*) 
usage 
;; 
esac
5. 部署

linux服务器上新建个文件夹,将我们打好的项目jar包都丢进去,在jar包的同级目录新建config和lib文件夹,分别将配置文件和第三方依赖包丢进去,其结构如下图,*.sh为自己写的项目启动shell脚本

打开config内的springboot核心文件(如application-demo1.properties文件),

spring.profiles.path配置项改成当前配置文件所在的目录,假设为/usr/local/demo/config

打开*.sh脚本,修改APPFILE_PATH的值,如下

APPFILE_PATH="-Dspring.config.location=/usr/local/demo/config/application-demo1.properties"

6. 项目管理

进入jar包所在目录执行下面命令

sh demo1.sh start 启动项目

sh demo1.sh stop 停止项目

sh demo1.sh restart重启项目

sh demo1.sh status项目状态
————————————————
转载:https://blog.csdn.net/xrq0508/article/details/80050119

springboot项目实现jar包外配置文件管理的更多相关文章

  1. 【转载】JAVA SpringBoot 项目打成jar包供第三方引用自动配置(Spring发现)解决方案

    JAVA SpringBoot 项目打成jar包供第三方引用自动配置(Spring发现)解决方案 本文为转载,原文地址为:https://www.cnblogs.com/adversary/p/103 ...

  2. SpringBoot项目打成jar包后上传文件到服务器 目录与jar包同级问题

    看标题好像很简单的样子,但是针对使用jar包发布SpringBoot项目就不一样了.当你使用tomcat发布项目的时候,上传文件存放会变得非常简单,因为你可以随意操作项目路径下的资源.但是当你使用Sp ...

  3. SpringBoot项目打成Jar包时运行

    使用java -jar ***.jar执行jar包的时候,会找jar包中的main()方法. 对于SpringBoot项目的Jar包,在META-INF目录下的MANIFEST.MF文件中,Main- ...

  4. JAVA SpringBoot 项目打成jar包供第三方引用自动配置(Spring发现)解决方案

    本项目测试环境 JDK: 1.8 SpringBoot: 2.1 需求描述 当我们想要利用SpringBoot封装一套组件并发布给第三方使用时,我们就不得不考虑我们的组件能否被使用者正确引入使用,此处 ...

  5. 使用gradle构建多模块springboot项目,打jar包

    官方文档: https://spring.io/guides/gs/rest-service/  参考:http://blog.csdn.net/u013360850/article/details/ ...

  6. 解决springboot项目打成jar包部署到linux服务器后上传图片无法访问的问题

    前言:目前大三,自己也在学习和摸索的阶段.在和学校的同学一起做前后端分离项目的时候,我们发现将后端打包成jar,然后部署到服务器中通过java -jar xxx.jar运行项目以后,项目中存在文件上传 ...

  7. eclipse中,将springboot项目打成jar包

    1.右击项目,选择Run As - Maven clean 2.右击项目,选择Run As - Maven install 3.成功后 会在项目的target文件夹下生成jar包 4.将打包好的jar ...

  8. Springboot项目打成jar包运行 和 打成war包 外部tomcat运行

    Jar打包方式运行 类型为jar时 <packaging>jar</packaging> 1.使用命令mvn clean  package 打包 2.使用java –jar 包 ...

  9. springboot项目打成jar包后台运行在linux上

    背景:springboot2为为主体搭建的项目,直接打成jar包,上传到linux上面 启动项目:java -jar xx.jar 这样很方便,但是不能关闭窗口,否则项目就停了 后台启动: nohup ...

随机推荐

  1. 修复grub

    进入命令行模式,#chroot /mnt/sysimage :切换根目录#grub2-install /dev/sda :安装grub2到第一硬盘#grub2-mkconfig -o /boot/gr ...

  2. [kuangbin 带你飞] DP专题——HDU - 1024

    Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  3. Scala(一)——scala+Idea环境配置

    Java虚拟机的确是很强大,有很多计算机语言可以运行在虚拟机上,完善了虚拟机上多语言编程. 近年来,大数据云计算,大数据的火爆也让一些小众语言火了起来,如Python,Scala等.这些语言编写简单, ...

  4. 爬虫之xpath解析库

    xpath语法: 1.常用规则:    1.  nodename:  节点名定位    2.  //:  从当前节点选取子孙节点    3.  /:  从当前节点选取直接子节点    4.  node ...

  5. ServiceComb 集成 Shiro 实践|火影专场发布

    Shiro简介 Apache Shiro是一款功能强大.易用的轻量级开源Java安全框架,它主要提供认证.鉴权.加密和会话管理等功能.Spring Security可能是业界用的最广泛的安全框架,但是 ...

  6. EL表达式和JSTL(一)

    一. 初始JavaBean 在软件开发时,有些数据时经常要用到的,为了方便进行移植,Sun公司提出了一种JavaBean技术,使用JavaBean对这些数据进行封装,做到一次编写,到处开发. Java ...

  7. UML-类图-需要写关联名称吗?

    概念模型:需要写关联名称:类图:不需要写关联名称. 注意,概念模型关联线不需要箭头.

  8. python画图例子代码

    matplotlib包,使得python可以使用类似matlab的命令 双坐标,子图例子 fig, axes = plt.subplots( 2,1, figsize=(14, 14) ) ax = ...

  9. reactor-core

    <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core&l ...

  10. Vue环境搭建-项目的创建-启动生命周期-组件的封装及应用

    vue项目环境的搭建 """ node >>> python:node是用c++编写用来运行js代码的 npm(cnpm) >>> p ...