通过文件覆盖类里面的属性–一种配置文件的另类实现方式

背景: 假设有这么一个场景,你写的jar包或者源代码服务提供给别人使用,你的默认配置是写在类里面的,如何通过一个ini文件来修改你写在类里面的配置呢? 毕竟用户不应该去修改你的代码,而是仅仅通过文件配置来实现配置的修改。

在一般的框架层面,系统已经支持的很好,例如spring boot的application.properties就是做这个事情的。另外,maven的插件也可以实现antx.properties的动态替换,下面我们用Java的反射手工的实现这么一个功能。

ConfigClass.java 配置文件

package top.huster.configfile;

/**
 * Created by longan.rtb on 17/8/31.
 */
public class ConfigClass {

    public  static String a = "";

    private  static  String b = "abc";


    public  static int testInt = 123;

    public  static int serverPort = 8080;

    public  static int serverThreadCount = 10;

    public String toString() {
        return "a is "
                + a
                + " \r\n b is "
                + b
                + "\r\n"
                + " testInt is "
                + testInt
                + "\r\n serverPort is "
                + serverPort
                + "\r\n serverThreadCount is "
                + serverThreadCount;
    }

}

主要执行类


package top.huster.configfile;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Created by longan.rtb on 17/8/31.
 */
public class SetClass {

    public static void main(String[] args) {
        HashMap<String, Field> fieldHashMap = new HashMap<>();
        Field[] fields = ConfigClass.class.getFields();
        for (Field f : fields) {
            f.setAccessible(true);
            fieldHashMap.put(f.getName(), f);
        }
        ConfigClass configClass = new ConfigClass();
        System.out.println(configClass.toString());
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("/tmp/config.ini"));
            for (Map.Entry<Object, Object> e : properties.entrySet()) {
                String k = (String) e.getKey();
                String v = (String) e.getValue();
                Field f = fieldHashMap.get(k);
                if (null == f) {
                    continue;
                }
                try {
                    if (Boolean.TYPE == f.getType())
                        f.set(configClass, Boolean.parseBoolean(v));
                    else if (Integer.TYPE == f.getType())
                        f.set(configClass, Integer.parseInt(v));
                    else if (Long.TYPE == f.getType())
                        f.set(configClass, Long.parseLong(v));
                    else if (String.class == f.getType())
                        f.set(configClass, v);
                } catch (Exception es) {
                    es.printStackTrace();
                }
            }
            System.out.println(configClass.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

配置文件config.ini

a = 123121
b = cddfadf
testInt = 88888
serverPort = 9999
serverThreadCount = 100

 

输出结果:

a is
b is abc
testInt is 123
serverPort is 8080
serverThreadCount is 10
a is 123121
b is abc
testInt is 88888
serverPort is 9999
serverThreadCount is 100

可以看到的是b因为是private属性,所以没有被覆盖。

这个程序主要借助的是Field这个对象。

 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注