关于自定义程序打包成jar包,并读取配置
前言
在实际开发过程中,我们有时候有把你编写的一段程序打成jar包的需求,而一些配置是需要去配置文件里面读取关于这项目的一些配置,本人在网络上查询了众多的资料,总的来说可以归为3类
1.从数据库读取配置
老生常谈,在dao层从数据库获取配置信息,然后返回到Service层进行业务逻辑处理
2.在每次调用这个jar的时候通过关键字去读取配置
在这一类中,方法有很多,不过大体都是
InputStream ins = getClass().getResourceAsStream("/resource/dbconfig.properties");
通过IO流对配置文件进行读取,然后再从 InputStream 流中读取数据,没什么技术含量,便不多讲
例如以下例子,就是通过Properties流来读取配置
/**
* 读取配置文件属性
* @param path 配置文件路径
* @return
* @throws IOException
*/
public Map readerConfigurationFile(String path) throws IOException {
/**
* 使用Properties读取配置文件并获取配置信息
*/
Properties properties = new Properties();
InputStream input = new BufferedInputStream(new FileInputStream(path));
properties.load(input); /**
* 将获取到的配置信息转存到map集合
*/
Map map = new HashMap();
for (Object key : properties.keySet()) {
if (properties.get(key) != null && !properties.get(key).toString().trim().equals("")){
map.put(key,properties.get(key));
}
}
return map;
}
3.通过Spring 自动装配,在项目启动时就把配置信息发送到jar包里面(强烈推荐)
这个方法虽然前期建立的时候比较繁琐,但是完成之后简直方便到飞起
首先,建立一下格式的结构,方便我们后面能够快捷找到要编写的文件

实际上DemoApplication.java 是可以去掉的,只是个人为了方便测试写的代码,看是否有bug就留下来启动项目用的
最最最重要的pom.xml文件应该这样写:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-->--------------------这里是自己jar的情况,自己编写--------- -------<-->
<modelVersion>4.0.0</modelVersion> <groupId>com.transfer</groupId> <artifactId>DataTransferService</artifactId> <version>0.0.1-SNAPSHOT</version> <name>DataTransferService</name> <description>DataTransferService</description> <properties> <spring-boot.version>2.6.13</spring-boot.version> </properties>
<!-->---------------------------------------------------------------<-->
<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> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency> <!-- 自动配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- 配置属性 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional><!-- 依赖不传递 -->
</dependency> <!--Lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency> <!--mysql数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build> </project>
在config包里面,我们要建立几个配置文件:
UserConfiguration.java
@Slf4j
@Configuration
@ConditionalOnExpression("${enabled:true}")
@EnableConfigurationProperties(UserConfiguration .class)
public class UserConfiguration { @Bean
@Primary
public UserConfig getConfigValue(UserProperties properties){
if (properties.getLog()){
log.info("数据库中转服务API组件 ——> 开启组件");
}
return new UserConfig()
.setOtherDataSourcesMap(properties.getOtherDataSourcesMap())
.setLog(properties.getLog());
}
}
UserConfig.java
@Data
@Accessors(chain = true)
public class UserConfig implements Serializable {
private Map<String,Map<String,Map<String,Object>>> otherDataSourcesMap; /** 是否打印操作日志 */
private Boolean log = true;
}
@Data
@ConfigurationProperties(prefix = "User")
public class UserProperties implements Serializable { private Map<String,Map<String,Map<String,Object>>> otherDataSourcesMap; /** 是否开启 */
boolean enabled = true; /** 是否打印操作日志 */
private Boolean log = false;
}
请注意:这里的@ConfigurationProperties 注解里面的 prefix 参数指的是在配置文件中你自己定义的标识符
public class UserBeanInject {
/**
* 注入配置Bean
*
* @param config 配置对象
*/
@Autowired(required = false)
public void setConfig(UserConfig config){
UserSpi.setConfig(config);
}
}
当然,还有重要的一步,那就是在resources文件夹下创建一个Spring自动装配的约定文件,使得我们这几个java配置文件能够生效

spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
自己定义的包路径.configuration.UserConfiguration, \
自己定义的包路径.configuration.UserBeanInject
然后,我们要暴露这个接口
@Slf4j
public class UserSpi{
public volatile static UserConfig config; public static void setConfig(UserConfig config){
UserSpi.config = config;
if (config.getLog()){
log.info("数据库中转服务API组件 ——> 打印配置信息\n", JSONUtil.toJsonStr(UserSpi.config));
}
} // =================== 获取Api 相关 =================== public static IUserService api = new UserServiceImpl();
}
这样基本上完成jar自动装配外部配置文件的配置,业务逻辑什么的看个人习惯自己去编写
感言
- 从数据库里面读取配置信息方便时挺方便的,但是在高并发与高请求的项目中并不适用,而每次调用这个jar的时候通过关键字去读取配置会造成内存资源不断被刷新,容易内存爆炸,个人推荐第3种方式。
- 还有,每次该改写完代码,一定要重新构建项目,重新编译一下,不然你打出来的Jar包,永远都是你改写之前的代码,改写之后的代码不会写入到Jar包里面!!!!
- 对了,直接把配置文件里面的值直接传递到jar包里面也是一种方法,但是要是被半路拦截,岂不是直接泄露数据,故不提倡,还有一点,就是代码的可维护性会变得很低
关于自定义程序打包成jar包,并读取配置的更多相关文章
- Java程序打包成jar包
方法一:通过jar命令 jar命令的用法: 下面是jar命令的帮助说明: 用法:jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] ...
- Java之 将程序打包成jar包
准备材料: 1.java文件: Helloworld.java package com.ray; public class HelloWorld{ public static void main(St ...
- [Java] Java 打包成jar包 和 解压jar包
解压jar包 jar xf xxx.jar 打包成jar包 方法一:通过jar命令 jar命令的用法: 下面是jar命令的帮助说明: 用法:jar {ctxui}[vfm0Me] [jar-file] ...
- 转载:java程序打包成jar 配置文件信息路径
一个普通的java project,里面引用了config.properties配置文件,将项目打成Runnable jar,然后将config.properties放到打包后的jar路径下,执行该j ...
- java程序打包成jar 配置文件信息路径
一个普通的java project,里面引用了config.properties配置文件,将项目打成Runnable jar,然后将config.properties放到打包后的jar路径下,执行该j ...
- [JAR包] android引入JAR包,打包成JAR包,打包成Library项目,导入Library项目
(1)项目导入JAR包:1.在项目目录里建立一个libs目录,将外部jar包拷贝在里面.2.右键点击项目,Bulid Path->Configure Build Path3.在设置Libraie ...
- 【spring boot】idea下springboot打包成jar包和war包,并且可以在外部tomcat下运行访问到(转)
转自:https://www.cnblogs.com/sxdcgaq8080/p/7727249.html 接着上一章走呗:http://www.cnblogs.com/sxdcgaq8080/p ...
- Android studio 将 Module 打包成 Jar 包
整理记录 AndroidStudio 把一个 module 项目打包成 jar 包. 一.默认自动生成的 jar 包 众所周知 android studio 会在library所依赖的 app运行 或 ...
- maven把项目打包成jar包后找不到velocity模板的bug
使用springmvc 开发时候要实现发送velcotiy模板邮件,在配置正常后,在本地测试正常后,使用maven打包成jar包后,报以下错误, Caused by: org.apache.veloc ...
- 【spring boot】6.idea下springboot打包成jar包和war包,并且可以在外部tomcat下运行访问到
接着上一章走呗:http://www.cnblogs.com/sxdcgaq8080/p/7712874.html 然后声明一点,下面打包的过程中,scope一直都是使用默认的范围 <!--用于 ...
随机推荐
- .NET开源分布式锁DistributedLock
一.线程锁和分布式锁 线程锁通常在单个进程中使用,以防止多个线程同时访问共享资源. 在我们.NET中常见的线程锁有: 自旋锁:当线程尝试获取锁时,它会重复执行一些简单的指令,直到锁可用 互斥锁: Mu ...
- Python + 超级鹰 识别图形验证码
前言: 一.下载 1.进入官网:http://www.chaojiying.com/,注册完成后,进行登录 2.点击开发文档,点击Python语言示例 3.进行示例下载 4.解压后的文件 注:关注公众 ...
- 用go设计开发一个自己的轻量级登录库/框架吧(项目维护篇)
用go设计开发一个自己的轻量级登录库/框架吧(项目维护篇) 本篇将开始讲讲开发库/框架的最开始阶段,也就是搭建一个项目 源码:weloe/token-go: a light login library ...
- react之todoList基础小项目
1.项目最终成品和项目目录快照如图: 2.context.js文件 // 使用context进行多级传递数据 // 1. createContext 创建一个可以多级传递的context数据 // 2 ...
- 2022-11-22:小美将要期中考试,有n道题,对于第i道题, 小美有pi的几率做对,获得ai的分值,还有(1-pi)的概率做错,得0分。 小美总分是每道题获得的分数。 小美不甘于此,决定突击复习,
2022-11-22:小美将要期中考试,有n道题,对于第i道题, 小美有pi的几率做对,获得ai的分值,还有(1-pi)的概率做错,得0分. 小美总分是每道题获得的分数. 小美不甘于此,决定突击复习, ...
- django视图中使用return redirect(reverse('')) 没有传参出现题:Reverse for ‘‘ with no arguments no arguments not
redirect 的作用是跳转 reverse的作用是反向解析 当无法反向解析的时候要确认urls.py中的path参数,name参数是否一直
- Anaconda网址
Anaconda: python全家桶,之前还有32位,现在需要64位. 官方网址:https://www.anaconda.com/ 国内源:https://mirrors.tuna.tsinghu ...
- 【GiraKoo】Android监听屏幕尺寸变化通知
[GiraKoo]Android监听屏幕尺寸变化通知 Android系统中存在多种情况可能导致屏幕尺寸发生变化.例如:横竖屏切换,虚拟按键,分屏,键盘弹出等. App有的时候需要了解屏幕的真实尺寸,D ...
- es笔记五之term-level的查询操作
本文首发于公众号:Hunter后端 原文链接:es笔记五之term-level的查询操作 官方文档上写的是 term-level queries,表义为基于准确值的对文档的查询,可以理解为对 keyw ...
- Python基础 - 标识符命名规范
标识符是什么? 标识符主要用来给变量名,函数名,方法名,类名起名时要遵循的规范 硬性规则 见名知意(使用中文转译后的英文) 由字母,数字,下划线组成, 并且不能以数字开头, 不能和Python关 ...