背景: 假设有这么一个场景,你写的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这个对象。