【仅供内部供应商使用,不提供对外解答和培训】
【仅供内部供应商使用,不提供对外解答和培训】
public class Config { private String b = "11"; private Date date = new Date(); private List<Date> birth = new ArrayList<Date>; private List<Test> tests = new ArrayList<Test>(); private Map<String,Integer> maps = new HashMap<>(); private Test test = new Test(); private Provider provider = new ProviderImpl(); private List<Provider> providers = new ArrayList<>(); private Map<String,Provider> absMap = new HashMap<>(); private Map<String,Test> expMap = new HashMap<>(); private List<String> priCol = new ArrayList<>(); public String getNameSpace(){ return "config"; } } public class Test { private int a; public Test() { } public Test(int a) { this.a = a; } public void setA(int a) { this.a =a; } public int getA() { return this.a); } } public interface Provider { } public class ProviderImpl extends UniqueKey implements Provider { private String a = "22"; public ProviderImpl(){ } public void setA(String a){ this.a = a; } public String getA(){ return this.a; } }
这边的getNameSpace表示的是这个配置对象所在的空间,用于不同对象的隔离。
package com.fr.config.holder.factory; import com.fr.config.holder.Conf; import com.fr.config.holder.impl.ColConf; import com.fr.config.holder.impl.MapConf; import com.fr.config.holder.impl.ObjConf; import com.fr.config.holder.impl.ObjectColConf; import com.fr.config.holder.impl.ObjectMapConf; import com.fr.config.holder.impl.SimConf; import java.util.Collection; import java.util.Map; /** * 包装类工厂 * http://www.finedevelop.com/pages/viewpage.action?pageId=18648778 */ public class Holders { /** * 创建一个基本类型的Holder类,只要T对象中没有成员变量ConfigHolder,就要用这个包装器 * * @param property 属性标签 * @param t 默认值 * @param nameSpace 名字空间 * @param <T> 包装的值类型 * @return 属性节点的包装 * @see Holders#simple(Object) */ @Deprecated public static <T> Conf<T> simple(String property, T t, String nameSpace) { return new SimConf<T>(property, t).setNameSpace(nameSpace); } public static <T> Conf<T> simple(T t) { return new SimConf<T>(t); } /** * 创建一个类型为T的对象的Holder,这个对象T里面会有ConfigHolder成员变量 * * @param property 属性标签 * @param t * @param type * @param nameSpace 名字空间 * @param <T> * @return 属性节点的包装 * @see Holders#obj(Object, Class) */ @Deprecated public static <T> Conf<T> obj(String property, T t, Class<T> type, String nameSpace) { return new ObjConf<T>(property, t, type).setNameSpace(nameSpace); } public static <T> Conf<T> obj(T t, Class<T> type) { return new ObjConf<T>(t, type); } /** * 创建一个类型K(基本类型)的Collection的Holder,只要对象中没有成员变量ConfigHolder,就要用这个包装器 * * @param property 属性标签 * @param collection * @param valueType * @param nameSpace 名字空间 * @param <K> * @return 属性节点的包装 * @see Holders#objCollection(Collection, Class) */ @Deprecated @SuppressWarnings("unchecked") public static <K> Conf<Collection<K>> collection(String property, Collection<K> collection, Class<K> valueType, String nameSpace) { return new ColConf(property, collection, valueType).setNameSpace(nameSpace); } @SuppressWarnings("unchecked") public static <K> ColConf<Collection<K>> collection(Collection<K> collection, Class<K> valueType) { return new ColConf(collection, valueType); } /** * 创建一个类型T的Collection的Holder,这个对象T里面会有ConfigHolder成员变量 * * @param property 属性标签 * @param collection * @param type * @param nameSpace 名字空间 * @param <T> * @return 属性节点的包装 * @see Holders#collection(Collection, Class) */ @Deprecated public static <T> ObjectColConf<Collection<T>> objCollection(String property, Collection<T> collection, Class<T> type, String nameSpace) { return new ObjectColConf<Collection<T>>(property, collection, type).setNameSpace(nameSpace); } public static <T> ObjectColConf<Collection<T>> objCollection(Collection<T> collection, Class<T> type) { return new ObjectColConf<Collection<T>>(collection, type); } public static <T> ObjectColConf<Collection<T>> objCollection(Collection<T> collection, Class<T> type, boolean order) { return new ObjectColConf<Collection<T>>(collection, type, order); } /** * 创建一个key和value均为基本类型的Map的Holder。只要K,V对象中没有成员变量ConfigHolder,就要用这个包装器,keyType和valueType均不能为空 * * @param property 属性标签 * @param map * @param keyType * @param valueType * @param nameSpace 名字空间 * @param <K> 包装的键值对中键类型 * @param <V> 包装的键值对中值类型 * @return 属性节点的包装 * @see Holders#map(Map, Class, Class) */ @Deprecated @SuppressWarnings("unchecked") public static <K, V> MapConf<Map<K, V>> map(String property, Map<K, V> map, Class<K> keyType, Class<V> valueType, String nameSpace) { return new MapConf(property, map, keyType, valueType).setNameSpace(nameSpace); } @SuppressWarnings("unchecked") public static <K, V> MapConf<Map<K, V>> map(Map<K, V> map, Class<K> keyType, Class<V> valueType) { return new MapConf(map, keyType, valueType); } /** * value是V类型的Map的Holder,这个对象V里面会有ConfigHolder成员变量 * K只能是基本类型或者字符串类型,又或者 K是一些简单的类型,这个不同的K对象可以转换成不同的String,注册K类型的ValueWriter对象,用来将K对象转换成String * 同样 也要注册K类型的ValueReader,用来从String中恢复重新构造K对象,ValueReader.registerReader, ValueWriter.registerWriter * keyType可以为空,但是map中的key只能是基本类型和String,ValueType可以为空,但是只能是复合类型。 * * @param property 属性标签 * @param map * @param keyType * @param valueType * @param nameSpace 名字空间 * @param <K> * @param <V> * @return 属性节点的包装 * @see Holders#objMap(Map, Class, Class) */ @Deprecated public static <K, V> ObjectMapConf<Map<K, V>> objMap(String property, Map<K, V> map, Class<K> keyType, Class<V> valueType, String nameSpace) { return new ObjectMapConf<Map<K, V>>(property, map, keyType, valueType).setNameSpace(nameSpace); } public static <K, V> ObjectMapConf<Map<K, V>> objMap(Map<K, V> map, Class<K> keyType, Class<V> valueType) { return new ObjectMapConf<Map<K, V>>(map, keyType, valueType); } public static <K, V> ObjectMapConf<Map<K, V>> objMap(Map<K, V> map, Class<K> keyType, Class<V> valueType, boolean ordered) { return new ObjectMapConf<Map<K, V>>(map, keyType, valueType, ordered); } }
1.生成成员变量b的Conf和生成成员变量Date的Conf
Conf<String> b = Holders.simple("11");
Conf<Date> date = Holders.simple(new Date());
什么情况下用Holders.simple?当这个对象是基本类型,String,一些jdk对象,枚举类型等一些我们不能够直接修改的对象,这些我们叫simple类型。
2.生成成员变量test的Conf和provider的conf
Conf<Provider> provider =Holders.obj(new ProviderImple(),Provider.class); 同样修改ProviderImpl
Conf<Test> test = Holders.obj(new Test(),Test.class);这边Test用Conf来封装,是因为Test是我们报表的业务对象,而且结构不是很复杂,那么我们除了要要修改Config中的test字段,还要修改Test类(和Holders.simple相比最大的区别是这个类是我们可以修改的,这些称之为复合类型),修改的方式如下,需要继承Uniquekey
public class Test extends UniqueKey { private Conf<Integer> a = Holders.simple(1); public Test() { } public Test(int a) { this.a.set(a); } public void setA(int a) { this.a.set(a); } public int getA() { return this.a.get(); } } public class ProviderImpl extends UniqueKey implements Provider { private Conf<String> a = Holders.simple("22"); public ProviderImpl(){ } public void setA(String a){ this.a.set(a); } public String getA(){ return this.a.get(); } }
3.生成成员变量maps的conf,Map中的元素是simple类型
MapConf<Map<String, Integer>> maps = Holders.map(new HashMap(),String.class,Integer.class);这个Map的key和value都为simple类型。
4.生成private List<Test> tests = new ArrayList<Test>(); private List<Provider> providers = new ArrayList<>();的holder,集合中的元素是复合类型
ObjectColConf<Collection<Test>> tests = Holders.objCollection(new ArrayList<Test>(),Test.class));//Test是具体的类
ObjectColConf<Collection<Provider>> providers=Holders.objCollection(new ArrayList<Provider>(),Provider.class);//Provider是接口
5.生成 private Map<String,Provider> absMap = new HashMap<>(); private Map<String,Test> expMap = new HashMap<>(); 的holder,value是复合类型
ObjectMapConf<Map<String,Provider>> absMap = Holders.objMap(new HashMap<String,Provider>(),String.class,Provider.class);
ObjectMapConf<Map<String,Test>> expMap = Holders.objMap(new HashMap<String,Test>(),String.class,Test.class);
如果外部需要修改absMap的值,比如put,则Config类提供方法
void putAbsMap(Object key,Object value){
this.absMap.put(key,value);
}
同样的对应其它集合类型的修改,也需要委托 ObjectMapConf和ObjectColConf修改的方法。禁止外部直接 获取 map,然后修改。
有的Xml配置类中有Xmlable的成员变量,有些xmlable比较简单,可以使用上述的复合类型的改写方式。
有的Xmlable实现很复杂,而且对外暴露的是接口类型,如果还是按照复合类型方式改写,要改写接口的全部实现,如果接口的实现还引用了其它复合类型,还需要将他们一起改写,这样会有超大的工作量,而且会污染原来的业务类,所以重新写了个Xmlable对象包装器,这个包装器依赖Xmlable的实现。
package com.fr.config.holder.factory; import com.fr.config.holder.Conf; import com.fr.config.holder.impl.xml.XmlColConf; import com.fr.config.holder.impl.xml.XmlConf; import com.fr.config.holder.impl.xml.XmlMapConf; import com.fr.stable.xml.XMLable; import java.util.Collection; import java.util.Map; /** * http://www.finedevelop.com/pages/viewpage.action?pageId=18648778 * 这是一个不被允许使用的类,配置文件都要求以单行的形式存储到数据库中,而不能使用直接存储xml文件 * 目前的存在是属于过渡期,还有太多以前是xml格式序列化的对象没有办法一一更改 */ @Deprecated public class XmlHolders { //复杂Xmlable类型对象,其中包含其她复杂的对象,这样会影响很多其它业务对象,用这个包装器,这个包装器依赖readxml和writeXml //存储格式是 假设当前对象的父空间是config,property 是 arr ,存储格式为config.arr XXXXXX xxx是这个xmlable对象的序列化结果 @Deprecated @SuppressWarnings("unchecked") public static <T extends XMLable> Conf<T> obj(String property, T t, Class<T> clazz, String nameSpace) { return new XmlConf(property, t, clazz).setNameSpace(nameSpace); } @SuppressWarnings("unchecked") public static <T extends XMLable> Conf<T> obj(T t, Class<T> clazz) { return new XmlConf(t, clazz); } //复杂Xmlable类型对象集合,其中包含其她复杂的对象,这样会影响很多其它业务对象,用这个包装器,这个包装器依赖readxml和writeXml //存储格式是 假设当前对象的父空间是config,property 是 arr ,我会为集合中的对象随机分配一个id // 存储格式为config.arr.id XXXXXX xxx是这个xmlable对象的序列化结果 @Deprecated public static <T extends XMLable> XmlColConf<Collection<T>> collection(String property, Collection<T> t, Class<T> clazz, String nameSpace) { return new XmlColConf<Collection<T>>(property, t, clazz).setNameSpace(nameSpace); } public static <T extends XMLable> XmlColConf<Collection<T>> collection(Collection<T> t, Class<T> clazz) { return new XmlColConf<Collection<T>>(t, clazz); } //复杂Xmlable类型对象Map,其中包含其她复杂的对象,这样会影响很多其它业务对象,用这个包装器,这个包装器依赖readxml和writeXml ////存储格式是 假设当前对象的父空间是config,property 是 arr , // 存储格式为config.arr.key XXXXXX xxx是这个xmlable对象的序列化结果 //K只能是基本类型或者字符串类型,又或者 K是一些简单的类型,这个不同的K对象可以转换成不同的String,注册K类型的ValueWriter对象,用来将K对象转换成String //同样 也要注册K类型的ValueReader,用来从String中恢复重新构造K对象 @Deprecated public static <K, V extends XMLable> XmlMapConf<Map<K, V>> map(String property, Map<K, V> t, Class keyType, Class<V> clazz, String nameSpace) { return new XmlMapConf<Map<K, V>>(property, t, keyType, clazz).setNameSpace(nameSpace); } public static <K, V extends XMLable> XmlMapConf<Map<K, V>> map(Map<K, V> t, Class keyType, Class<V> clazz) { return new XmlMapConf<Map<K, V>>(t, keyType, clazz); } }