项目启动时,将配置文件加载进常量。

工作中突发奇想,可否将配置常量中的数据写入配置文件,每次使用配置文件加载常量。

配置文件

const.properties

FTP_HOST_NAME = 192.168.2.90
FTP_PORT = 21


FFMPEG_EXE = /usr/local/Cellar/ffmpeg/4.1_1/bin/ffmpeg
FFPROBE_EXE = /usr/local/Cellar/ffmpeg/4.1_1/bin/ffprobe

存放常量的类

public class Const {


    public static final String FTP_HOST_NAME = null;

    public static final String FTP_PORT = null;

    public static final String FFMPEG_EXE = null;

    public static final String FFPROBE_EXE = null;
}

程序

​
​
package com.test.config;


import org.springframework.core.io.ClassPathResource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

/*
 * @Description: 自动将配置文件中的数据载入静态类
 */
public class AutoProperties {


	//当配置文件中的属性找不到对应的常量时,会空指针异常
	public static void init() {

		//需要加载的配置文件
		List<String> constPaths = new ArrayList<>();
		constPaths.add("classPath:config/const.properties");

		//对应配置文件坐标加载的类
		List<String> classPaths = new ArrayList<>();
		classPaths.add("com.aiface.util.Const");


		autoPropertieByList(constPaths,classPaths);
	}

	//根据两个对应的list创建给常量赋值
	public static void autoPropertieByList(List<String> constPaths,List<String> classPaths){
		for (int i = 0; i < constPaths.size(); i++) {
			InputStream inputStream = null;
			try {
				String propertiePath = constPaths.get(i);
				//判断是否是classpath目录下的配置文件
				if (propertiePath.contains("classPath:")) {
					propertiePath = propertiePath.replace("classPath:","");
					ClassPathResource classPathResource = new ClassPathResource(propertiePath);
					inputStream = classPathResource.getInputStream();
				}else{
					File file = new File(propertiePath);
					inputStream = new FileInputStream(file);
				}
				autoPropertie(inputStream, classPaths.get(i));
			} catch (Exception e) {
				System.out.println("自动填充Conts属性失败");
				e.printStackTrace();
			} finally {
				if (inputStream != null) {
					try {
						inputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}




	//自动填充我的配置文件
	public static void autoPropertie(InputStream inputStream, String classPath) throws Exception {
		//获取配置文件中的所有属性
		Properties pro = new Properties();
		pro.load(inputStream);
		Iterator<String> it = pro.stringPropertyNames().iterator();
		while (it.hasNext()) {
			String key = it.next();
			String value = pro.getProperty(key);
			modify(classPath, key, value);
		}

	}


	//通过反射修改一个final修饰的类
	public static void modify(String classPath, String fieldName, Object newFieldValue) throws Exception {
		//通过路径获取类文件
		Class<?> c1 = Class.forName(classPath);
		Field field = c1.getDeclaredField(fieldName);
		Field modifiersField = Field.class.getDeclaredField("modifiers");
		modifiersField.setAccessible(true); //Field 的 modifiers 是私有的
		modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
		if (!field.isAccessible()) {
			field.setAccessible(true);
		}
		field.set(c1, newFieldValue);
	}

	

}

​

​

需要加载的配置文件和需要填充的常量类使用下标一一对应。

可以填充多个配置文件和存放常量的类

Springboot使用

在项目启动前填充存放常量的类。

@SpringBootApplication
@EnableDiscoveryClient
@EnableAsync //开启异步调用
public class AifaceWebApplication {
	public static void main(String[] args) {
		AutoProperties.init();
		SpringApplication.run(AifaceWebApplication.class, args);
	}
}

普通web项目

在监听器中配置一下(具体省略。。。。。)。

途中遇到的问题

Spring boot 读取resource下的properties文件。

Spring boot 在打包后变成了一个jar包,我们无法通过io流的方式读取配置文件了。

public static void getResoure(String resoure) throws IOException {
		//resoure 不带classpath前缀哦
		ClassPathResource classPathResource = new ClassPathResource(resoure);
		InputStream inputStream = classPathResource.getInputStream();
		Properties pro = new Properties();
		pro.load(inputStream);
		Iterator<String> it = pro.stringPropertyNames().iterator();
		while (it.hasNext()) {
			//得到key 和value的值
			String key = it.next();
			String value = pro.getProperty(key);
		}
	}

通过反射修改一个常量

/*
	* @Description:通过反射修改一个常量
	* @params classPath 类路径 如 com.abc.test.java
	* @params fieldName 常量的名字
	* @params newFieldValue 赋予的值
	* @return void
	* @date 2019/3/6 6:11 PM
	*/
	public static void modify(String classPath, String fieldName, Object newFieldValue) throws Exception {
		//通过路径获取类文件
		Class<?> c1 = Class.forName(classPath);
		Field field = c1.getDeclaredField(fieldName);
		Field modifiersField = Field.class.getDeclaredField("modifiers");
		modifiersField.setAccessible(true); //Field 的 modifiers 是私有的
		modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
		if (!field.isAccessible()) {
			field.setAccessible(true);
		}
		field.set(c1, newFieldValue);
	}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SUNbrightness

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值