【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Current »

1.配置文件前世:

配置文件都继承自XMLFileManager,需要提供readXml和writeXml方法的实现,其中每个xml读写都有深深的硬编码的烙印,这就导致了不同xml文件的读写实现都紧紧与内部数据结构耦合,因此每个xmlFileManager的读写实现都有很强的个性,导致难以从外部进行读写抽象。

在xml文件的实现类中,包含了很多成员变量,有一些基本类型(直接写标签),有一些XmLable的实现(也实现了readXml和writeXml方法,当读写这些变量时,委托他们各自的实现来进行读写),还有一些普通对象(这些对象没有实现readXml和writeXml,只是记录了一下对象里面的信息,读取的时候根据这些信息重新构造对象)

比如ConfigManager中,有成员变量(基本类型) private String resServerPath,直接在xml里面定义一个标签,然后把值写进去,有成员变量(实现了Xmlable接口)private EmbeddedTableData embeddedTableData,读写的时候直接调用embeddedTableData.readXml和writeXml,还有成员变量(普通对象)private Map styleMap = new ListMap(); key为String,value为Style,其中Style就是样式,写入的时候直接暴力记录Style里面信息,读取的时候根据这些信息重新构建Style。因为对象的读写没有一些强制的约束,所以基本上不可能从外部抽象文件读写。

2.配置文件今生

基于以上原因,只能侵入配置文件内部,来逐层代理各个成员变量(这里面用ConfigHolder来进行封装,所有的读写逻辑根据代理对象的类型,由ConfigHolder来处理),这样至少可以保证配置文件类对外提供的接口不变。API提供了几个生成holder的工厂类,来生成各种holder。工厂类如下

(修改了工厂接口,不需要写property和nameSpace,property默认时成员变量的变量名,如果想自定义property,则在相应的成员变量上加注解Identifier)

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.如果成员变量是基本类型,String或者JDK的内置类型(不包括集合),则使用 Conf<T> xxx = Holders.simple(t));

2.如果成员变量是Map类型,而且Map的key和value类型都是是基本类型,String类型或者JDK的内置类型(不包括集合),则使用 MapConf<K,V> xx = Holdes.map(map,keyType,valueType); keyType和ValueType需要明确指定,另外MapConf提供了一些操作map的方法,比如get,put,remove和clear。如果有个配置文件A,其中有个成员变量B是这种类型,假如需要修改Map,则需要在A中提供修改B的方法,调用MapConf修改。外部修改B,严禁使用 A.getB.put方法,remove等方法,这样只会修改内存,不会进行持久化存储。

3.如果成员变量是集合类型,而且集合中的类型是基本类型,String或者JDK的内置类型,则使用ColConf<Collection<K>> xxxx = Holders.collection(collection,valueType);

4.如果成员变量是我们报表的业务对象,那么这个成员变量需要用Conf<T> tt = Holders.obj(t,type),同样的成员变量所在类中的成员变量也需要根据其类型用 Conf来进行包装,。

5.如果成员变量是集合类型,值为报表的业务对象,那么需要 用ObjectColConf<T> ttt = Holders.objCollection();,这个ObjectColConf提供了集合操作的 add,remove,clear方法,如果修改Collection中,需要在配置类中提供修改集合的方法,委托ObjectColConf来进行修改。

6.如果成员变量是Map类型,key为基本类型,String或者JDK的内置类型(不包括集合),value是报表的业务对象,那么要使用MapConf<Map<K.V>> kkk = Holders.map(map,keytype,valueType); keytype和valueType可以为空。

注意,如果是报表的业务对象,均需要继承UniqueKey.

这边有使用范例:1-配置文件前世今生

还有对一些复杂xmlable的包装类,(为啥还有提供呢,因为这些对象的结构复杂,涉及的类众多,会导致代理holder类层次过多,也会污染原来的业务对象,影响性能。直接包装Xmlable,委托其自身的readXml和writeXml来进行读写)

非常不推荐使用

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);
    }
}



以上所有用holder封装的Map的key只能是一些基本数据类型,八种基本类型的包装类型和String类型。又或者 K是一些简单的类型,这个不同的K对象可以转换成不同的String,注册K类型的ValueWriter对象,用来将K对象转换成String,ValueWriter.registerWriter,同样 也要注册K类型的ValueReader,用来从String中恢复重新构造K对象,ValueReader.registerReader。

  • No labels