背景

为实现快速搭建和开发,项目以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. JavaScript—面向对象贪吃蛇_1

    前面说了.面向对象的思考方式和面向过程的思考方式有着本质的区别. 贪吃蛇.作为各大培训机构.面向对象的练手项目,的确好.我昨天看完视频,有一种领悟面向对象的感觉,当然可能只针对贪吃蛇..要想在实际开发 ...

  2. idea抛出异常:org.apache.shiro.authc.AuthenticationException

    问题描述 继续在ubuntu下折腾,终于将web项目的所有的东西配置好了,然后运行项目,满怀期待的心情登录系统的时候,突然出现了这个bug,吓得我差点从椅子上跳起来,这两天遇到的bug实在是太多了.. ...

  3. share团队冲刺8

    团队冲刺第八天 昨天:完善代码,解决其中的问题 今天:将除登陆界面之外的界面进行修改和完善,使其美观 问题:bindview不会用,使用时出现问题

  4. JAVA初学者——标识符命名规则及数据类型的转换

    Hello!我是浩宇大熊猫~ 直接进入正题吧~ 1)标识符的命名规则. 标识符命名法有小驼峰命名法和大驼峰命名法两种,分别应用于方法.变量和类. 小驼峰命名法应用于方法和变量,主要有两个约定: 1.标 ...

  5. selenium滚动条应用,爬永远讲不完的故事

    from selenium import webdriver class Lj(object): def __init__(self): self.driver = webdriver.Chrome( ...

  6. LeetCode——714. 买卖股票的最佳时机含手续费.

    给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 :非负整数 fee 代表了交易股票的手续费用. 你可以无限次地完成交易,但是你每次交易都需要付手续费.如果你已经购买了一个 ...

  7. 吴裕雄--天生自然 PHP开发学习:MySQL 读取数据

    <?php $servername = "localhost"; $username = "root"; $password = "admin& ...

  8. 基于JSP开发医院预约挂号系统 Java源码

    开发环境: Windows操作系统 开发工具: Eclipse+Jdk+Tomcat+MYSQL数据库 运行效果图: 源码及原文链接:http://javadao.xyz/forum.php?mod= ...

  9. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis) 的学习实践总结【第四天】

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

  10. 函数(Python)

    函数是什么? 计算机的函数,是一个固定的一个程序段,或称其为一个子程序,它在可以实现固定运算功能的同时,还带有一个入口和一个出口,所谓的入口,就是函数所带的各个参数,我们可以通过这个入口,把函数的参数 ...