`
agapple
  • 浏览: 1583728 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

我也造了个轮子:BeanMapping(属性拷贝)

阅读更多

背景  

  最近公司在大力推进服务化平台,我在中间主要做一个orm框架,解决model和数据源之间的映射问题。这里不选择已有的hibrenate,主要考虑自己公司的一些特殊场景:比如多数据源(数据库,搜索引擎,memcached,nosql等),同时可以 做一些特殊优化,比如多数据源加载时采用并行加载(我之间做的一个工具包 (业务层)异步并行加载技术分析和设计)

 也不多罗嗦,我主要负责从多个数据源搜集回来的数据,构造成对应的model对象。可以看一下具体的分析过程。

 

分析

   每个数据源采集回来的数据可能比较凌乱,有map对象,POJO对象,至于这个映射过程。因为是在老系统上实施,以前都没有service的概念,在数据库的设计会很比较乱,都是来一个需求加几个字段的那一类型。 所以具体data -> model对象的映射过程,就需要额外考虑一些特殊功能。

 

需求整理: 

  1. 处理的data是个map对象
  2. 处理的data是个pojo bean
  3. 映射过程中,处理的data属性名和目标对象model的属性会大不相同
  4. 映射过程中,data中的数据大多都是文本型,而对应的model会是根据业务场景定义的强类型,需要有类型转化
  5. 对应的data可能是一个平面型的map/bean对象,需要转化有层次结构,带立体的模型。比如model里包含一些子model等
  6. 需要处理特殊情况,比如data中有个属性是个json格式数据,需要在解析后再转化到某几个model属性上

针对这些需求,回过头看一下现在比较流行的几个处理工具包: cglib , beanutils 。 
cglib(之间的一篇分享文档: cglib源码学习交流) : 素以性能著称,主要是BeanCopier,但功能很简单。主要是解决bean之间,同名属性的转化,功能无法满足
beanutils :  功能上支持到是还不错,可以支持处理map,pojo的转化,不同属性类型之间的转化,也可以支持nested子模型的映射。 但无法解决不同名属性之间的映射,json格式类似数据的处理,还有一个就是性能不咋的。根据原先的测试来看,应该是cglib性能的1/1000,相差了3个数量级。

基于如上的需求,以及对现有产品的优缺点分析,所以最后决定我要造一个轮子,刚开始其实还是本着完成项目。但后来发觉写着写着,越来越像那么回事,所以索性剥离了业务部分代码,安心的在底层先实现了一个BeanMapping的轮子。 

设计

  根据上面的需求分析,因为要解决不同属性名自己的映射关系,单纯的依赖bean属性的扫描无法满足。所以需要引入配置文件,定义mapping的映射关系。

 

整体设计示意图: 

说明: 

 

  • 将属性mapping的动作抽象成Get / Set两个操作。 Get操作针对数据源对象,Set操作针对数据目标对象
  • 在Get/Set中间,定义了一个ValueProcess处理插件的概念,允许扩展相关的功能插件 (自认为相比于BeanUtils/BeanCopier的非常好的亮点,扩展性良好)
    1.  比如默认值
    2.  类型转化器
    3.  json数据处理
    4.  日志记录
Get/Set为整个框架的核心(core)实现,ValueProcess为框架的扩展点,允许自定义一些功能插件,默认已经提供了几个功能处理。

对应的类关系图: 

Get/Set操作类


 

ValueProcess设计类:


客户端使用类设计:



 

 

几个客户端API说明: 
  1. BeanMapping :  本轮子的核心功能,通过基于配置方式的mapping映射,支持convetor,defaultValue,script的所有功能。要求使用之前必须提前配置bean-mapping映射。
  2. BeanCopy 和 BeanMap : 都是一些扩展功能,基于本轮子的核心架构不变的基础上,开发了BeanUtils.copyProperties() , BeanUtils.describe,  BeanUtils.populate()的功能。 使用该api,可以不需要配置映射文件,会进行自动扫描,就是基于同名属性的处理前提。
  3. BeanMappingUtil : 提供了BeanMapping , BeanCopy , BeanMap的所有方法,提供静态的util方法处理。每次都会构造对应的BeanMapping等对象,注意:每次进行构造BeanCopy,BeanMap,解析的属性结果会有cache。所以使用该util不会有很明显的性能下降,无非就是多一些临时对象。

最后定义的配置文件示例:  mapping.xml

 

<bean-mappings xmlns="http://mapping4java.googlecode.com/schema/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://mapping4java.googlecode.com/schema/mapping http://mapping4java.googlecode.com/svn/trunk/src/main/resources/META-INF/mapping.xsd">
    <!--  (bean-bean) mapping 测试 -->
    <bean-mapping batch="true" srcClass="com.agapple.mapping.object.SrcMappingObject" targetClass="com.agapple.mapping.object.TargetMappingObject" reversable="true">
    	<field-mapping srcName="intValue" targetName="intValue" />
    	<field-mapping targetName="integerValue" script="src.intValue + src.integerValue" /> <!-- 测试script -->
    	<field-mapping srcName="start" targetName="start" />
    	<field-mapping srcName="name" targetName="targetName" /> <!--  注意不同名 -->
    	<field-mapping srcName="mapping" targetName="mapping" mapping="true" />
    </bean-mapping>
    
    <bean-mapping batch="true" srcClass="com.agapple.mapping.object.NestedSrcMappingObject" targetClass="com.agapple.mapping.object.NestedTargetMappingObject" reversable="true">
    	<field-mapping srcName="name" targetName="name" defaultValue="ljh" /> <!-- 测试default value -->
    	<field-mapping srcName="bigDecimalValue" targetName="value" targetClass="string" defaultValue="10" /> <!-- 测试不同名+不同类型+default value  -->
    </bean-mapping>

</bean-mappings>

说明:

  • bean-mappings :  可以指定xsd,方便编写配置文件。通过IDE可以给于提示
  • bean-mapping : 定义需要进行mapping映射的对象信息,需要指定class全路径
    reversable主要表明此mapping动作是可逆的,默认为true。 batch主要是一优化特性,后面再细表。
  • field-mapping : 主要定义需要进行映射的属性之间的映射关闭 srcName : 源对象的属性名 srcClass : 源对象的class类型 targetName : 目标对象的属性名 targetClass : 目标对象的class类型 mapping : 表明是否需要进行递归映射,比如这里的,在处理NestedSrcMappingObject和NestedTargetMappingObject时,会递归进行映射处理 defaultValue : 很好理解,就是针对源属性为null时,默认值处理 convetor : 自定义类型转化器 (默认支持基本类型,BigDecimal,BigInteger,Array,List之间的转化处理) script : 高级特性,支持自定义的映射规则,比如这里进行一个+运算。
    targetName="integerValue" script="src.intValue + src.integerValue" 

几点说明: 

  1. srcClass/targetClass: 默认可不关注,系统会自动进行识别,在defaultValue和convetor转化处理。 还有一点:如果对象中出现同名的属性时,可以指定targetClass进行唯一定位
  2. defaultValue : 相比于BeanCopier和BeanUtils,一个特有的特性。 大家熟悉ibatis的配置就知道会有一个nullvalue配置,主要是方便客户端处理,避免进行一些无谓的==null/==0这样的处理
  3. convetor : 相比于BeanUtils, 这里允许声明属性之间的转化类,比如你注册了一个alias别名的convetor,就可以在这里声明进行使用,会优先使用你定义的(如果不指定,则会进行自动根据类型进行匹配)。
    自动处理会有个局限性,就是convetor会是全局性。比如你定义了一个String到Date的处理,以后整个jvm中所有的场景都会按照你定义的进行转化,到时候你怎么死自己都不知道
  4. script: 系统的高级特性,做为系统的一些扩展点,可以支持一些比较复杂的处理,比如以后的json/xml等处理,只需注册你的functions。比如这里定义: script="src.intValue + src.integerValue"。
使用例子

BeanMapping列子: BeanMappingTest.java

public BeanMapping srcMapping    = BeanMapping.create(SrcMappingObject.class, TargetMappingObject.class);
public BeanMapping targetMapping = BeanMapping.create(TargetMappingObject.class , SrcMappingObject.class);

@Test
public void testBeanToBean_ok() {
	SrcMappingObject srcRef = new SrcMappingObject();
	srcRef.setIntegerValue(1);
	srcRef.setIntValue(1);
	srcRef.setName("ljh");
	srcRef.setStart(true);

	TargetMappingObject targetRef = new TargetMappingObject();// 测试一下mapping到一个Object对象
	srcMapping.mapping(srcRef, targetRef);

	SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次
	targetMapping.mapping(targetRef, newSrcRef);
}

 

BeanCopy例子: (发觉和BeanCopier使用比较像)  BeanCopyTest.java

public BeanCopy srcCopyer    = BeanCopy.create(SrcMappingObject.class, TargetMappingObject.class);
public BeanCopy targetCopyer = BeanCopy.create(TargetMappingObject.class , SrcMappingObject.class);

@Test
public void testCopy_ok() {
	SrcMappingObject srcRef = new SrcMappingObject();
	srcRef.setIntegerValue(1);
	srcRef.setIntValue(1);
	srcRef.setName("ljh");
	srcRef.setStart(true);

	TargetMappingObject targetRef = new TargetMappingObject();// 测试一下mapping到一个Object对象
	srcCopyer.copy(srcRef, targetRef);

	SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次
	targetCopyer.copy(targetRef, newSrcRef);
}

 

BeanMap例子: (支持bean<->map的转化处理) BeanMapTest.java

public BeanMap beanMap = BeanMap.create(SrcMappingObject.class);

    @Test
    public void testDescribe_Populate_ok() {
        SrcMappingObject srcRef = new SrcMappingObject();
        srcRef.setIntegerValue(1);
        srcRef.setIntValue(1);
        srcRef.setName("ljh");
        srcRef.setStart(true);

        NestedSrcMappingObject nestedSrcRef = new NestedSrcMappingObject();
        nestedSrcRef.setBigDecimalValue(BigDecimal.ONE);
        srcRef.setMapping(nestedSrcRef);

        Map map = beanMap.describe(srcRef);

        SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次
        beanMap.populate(newSrcRef, map); // 从map属性设置到bean
    }

性能测试数据

不过前面功能说的如何天花乱坠,整个工具的性能相比也是大家比较会关注的一个点。 我这里大致做了下测试:构造一个CopyBean,基本涵盖了普通类型,对象处理等,进行批量处理

CopyBean : 

 

public class CopyBean {

        private int        intValue;
        private boolean    boolValue;
        private float      floatValue;
        private double     doubleValue;
        private long       longValue;
        private char       charValue;
        private byte       byteValue;
        private short      shortValue;
        private Integer    integerValue;
        private Boolean    boolObjValue;
        private Float      floatObjValue;
        private Double     doubleObjValue;
        private Long       longObjValue;
        private Short      shortObjValue;
        private Byte       byteObjValue;
        private BigInteger bigIntegerValue;
        private BigDecimal bigDecimalValue;
        private String     stringValue;
}

BeanCopy性能测试

对比的内容:

  • BeanCopy.copy 
  • BeanCopy.simpleCopy (不做类型转化)
  • Method.invoke
  • FastMethod.invoke 
  • BulkBean
  • BeanCopier
  • HardCode (硬编码,直接手工挨个复制属性)
  • PropertyUtils  (不做类型转化)
  • BeanUtils
说明: 因为beanUtils,PropertyUtils的性能太差,基本上其他的柱状图都看不清楚。


说明: 排除了PropertyUtils/BeanUtils的性能对比图,发现BeanMapping提供的copy方法可以比直接Method的反射调用略快一点,不过和cglib的BeanCopier还是有点差距,毕竟人家的功能支持的也很简单,很裸露的get/set调用。性能上基本也和直接硬编码写copy操作一样。

具体测试数据:
开启batch优化(200w次):单位ns 纯解释执行(排除JIT优化)(10w次):单位ns
BeanMapping.copy 1189 72780
BeanMapping.simpleCopy 1178 69381
Method 1322 25882
FastMethod 533 15961
BulkBean 108 4420
BeanCopier 18 1566
HardCopy 17 1376
PropertyUtils 22143 1037770
BeanUtils 43980 1766392
说明:
  • 首先注意一下,单位是ns。 1s = 1000ms = 1 * 10^9 ns
  • BeanCopier和手工编码写的copy性能基本接近
  • BeanMapping的copy和simpleCopy的区别,copy可以支持类型转化,simpleCopy不会处理类型转化。
  • BeanMapping的性能是BeanUtils的近40倍左右,不过和BeanCopier还是有些差距,大概在50倍左右。 (换另一个概念,就是执行100w次,BeanCopier可以比BeanMapping节省1秒,可以比BeanUtils节省40多秒,比较直观吧)

最后

 整个过程,完成功能代码大概只花了一周的时间,但是代码的重构/抽取,性能优化花了我近2周的时间。性能从最初的比BeanUtils慢,逐步的提升到了快几十倍,还是比较有成就感的。

 

还有一点,就是自己比较满意ValueProcess概念的设计,相比于BeanCopier或者BeanUtils扩展性好多了,比如自身系统的功能:日志记录,默认值,类型转化,script脚本(EL表达式)。都是通过扩展接口实现,也比较方便切换成不同的实现.。

 

有兴趣的同学,可以看下googlecode上的代码,有问题欢迎联系!

 

googlecode地址 :  http://code.google.com/p/mapping4java

 

相关功能测试代码:

BeanCopyTest.java 3.1 KB
BeanMapTest.java 2.1 KB
BeanMappingTest.java 7.8 KB
ConfigTest.java 1.7 KB
ConvertorTest.java 8.5 KB
ScriptExecutorTest.java 2.2 KB
ScriptTest.java 2.7 KB

 

性能测试代码: 

CopyPerformance.java 12.9 KB
MapPerformance.java 3.0 KB

 

需求搜集

结合了dozer的一些特性,也顺便整理了一下自己的后续action的一些功能点,做了适当取舍。 

 

issue列表: http://code.google.com/p/mapping4java/issues/list

  • 大小: 10.3 KB
  • 大小: 8.6 KB
  • 大小: 7.9 KB
  • 大小: 68.7 KB
  • 大小: 4.9 KB
  • 大小: 11 KB
  • 大小: 13.1 KB
  • 大小: 9.2 KB
  • 大小: 8.5 KB
分享到:
评论
48 楼 itstarting 2011-06-15  
agapple 写道


你描述的两个业务场景,基本上也就是我们现在遇到比较多的。只不过我们现在大范围进行重构,构建SOA服务时,第2个场景的问题就特别明显



OK,扯上了SOA,那就应该考虑叫做xmlbeanMapping更有用武之地,跟XMLBeans之流的对着干

有时候我倒是怀念起ETL
47 楼 bugu1986 2011-06-14  
agapple 写道
bugu1986 写道
agapple 写道
当然支持,只不过你得告诉我这是一个需要做深度复制的对象。默认只做第一层复制


你们淘宝带代码出来看起来还是蛮开放的。。。不像我们,不管涉不涉及业务,是代码就带不出来。。。

确实插件化的设计还是很赞的,另外用script在xml里面,我们的项目里也有用,感觉表达能力很强,很好。


从哪里看出有淘宝的信息? 呵呵,我非淘宝人员
可以这么说,代码是你自己写的。只不过用在公司的某个项目上而已
我们一般也会要求,涉及公司信息的代码或者信息不能在blog里讨论

来自杭州。。我经验主义了。。呵呵
46 楼 sammor 2011-06-14  
个人感觉挺好的,找个时间好好拜读下。
45 楼 agapple 2011-06-14  
itstarting 写道
使劲看了两遍,还是没看明白真正的应用场景,如果是定位于跟名字那样,bean mapping/conversion,本也是无可厚非的,但一开始那段提到了hibernate,以为是一个更猛的替代品——然而不是,对吧?

LZ看看是不是可以理解主要用于这些应用场景:
1、常见于MVC框架的form<->bean conversion?
2、基于pulling的Business Domain -> DAO持久化对象“自动”映射转换?(这个有点拗口,即访问业务模型,但业务模型跟DAO模型可以不一样,但可以自行trigger+转换?)

如果仅仅是bean的复制/转换+性能提升,就不要用这么多XML了吧,顶多用些简单的annotation——毕竟你也用JDK1.5以上了



其实你的annotation也是一种配置,只不过展示显示不同而已。
两种配置的选择,也是仁者见仁,智者见智的问题了。没必要太过于纠结

你描述的两个业务场景,基本上也就是我们现在遇到比较多的。只不过我们现在大范围进行重构,构建SOA服务时,第2个场景的问题就特别明显

引用
但一开始那段提到了hibernate,以为是一个更猛的替代品——然而不是,对吧?

哈哈,这个只是一个引子
44 楼 itstarting 2011-06-14  
使劲看了两遍,还是没看明白真正的应用场景,如果是定位于跟名字那样,bean mapping/conversion,本也是无可厚非的,但一开始那段提到了hibernate,以为是一个更猛的替代品——然而不是,对吧?

LZ看看是不是可以理解主要用于这些应用场景:
1、常见于MVC框架的form<->bean conversion?
2、基于pulling的Business Domain -> DAO持久化对象“自动”映射转换?(这个有点拗口,即访问业务模型,但业务模型跟DAO模型可以不一样,但可以自行trigger+转换?)

如果仅仅是bean的复制/转换+性能提升,就不要用这么多XML了吧,顶多用些简单的annotation——毕竟你也用JDK1.5以上了

43 楼 agapple 2011-06-14  
Reset 写道
agapple 写道
Reset 写道
agapple 写道

合并多次的get/set请求生成字节码调用(你可以理解为动态编译成类的属性调用)


我只能说 你的描述。。。比较难懂。。。


你就这么理解把,比如说我有100个属性要进行mapping。我可以是每次进行一个属性处理(每次都经过方法反射调用),也可以是一次性取出100个属性的值进行处理,会有一些细微的性能上的差别(可以提升几倍把)
你提的动态编译成类,你理解就是一个batch处理过程的一种方式,调用编译生成的类,批量的调用get方法。

这也是一些常见的优化处理,你看spymemcached,xmemcached都有类似的batch处理


你的解释让我有点糊嘟 你说的字节码调用 是指反射么后还是 class(字节码) ?


字节码调用是通过生成bytecode,你理解就是动态生成了一段已经编译了的代码。比如一段invokevirtual xxxMethod的代码。
正常的beanutils都是使用Method.invoke反射调用,jdk1.6之后反射调用的性能优化的已经很不错。 
42 楼 Reset 2011-06-14  
agapple 写道
Reset 写道
agapple 写道

合并多次的get/set请求生成字节码调用(你可以理解为动态编译成类的属性调用)


我只能说 你的描述。。。比较难懂。。。


你就这么理解把,比如说我有100个属性要进行mapping。我可以是每次进行一个属性处理(每次都经过方法反射调用),也可以是一次性取出100个属性的值进行处理,会有一些细微的性能上的差别(可以提升几倍把)
你提的动态编译成类,你理解就是一个batch处理过程的一种方式,调用编译生成的类,批量的调用get方法。

这也是一些常见的优化处理,你看spymemcached,xmemcached都有类似的batch处理


你的解释让我有点糊嘟 你说的字节码调用 是指反射么后还是 class(字节码) ?
41 楼 agapple 2011-06-14  
Reset 写道
agapple 写道

合并多次的get/set请求生成字节码调用(你可以理解为动态编译成类的属性调用)


我只能说 你的描述。。。比较难懂。。。


你就这么理解把,比如说我有100个属性要进行mapping。我可以是每次进行一个属性处理(每次都经过方法反射调用),也可以是一次性取出100个属性的值进行处理,会有一些细微的性能上的差别(可以提升几倍把)
你提的动态编译成类,你理解就是一个batch处理过程的一种方式,调用编译生成的类,批量的调用get方法。

这也是一些常见的优化处理,你看spymemcached,xmemcached都有类似的batch处理
40 楼 Reset 2011-06-14  
agapple 写道

合并多次的get/set请求生成字节码调用(你可以理解为动态编译成类的属性调用)


我只能说 你的描述。。。比较难懂。。。
39 楼 agapple 2011-06-14  
Reset 写道
我感觉如果拼速度的话,不如将你的xml映射 动态编译类 ,放到缓存 ,这个类实现某个接口,接口有2个方法,copyProperties(target,dist) ,isMapping(target,dist) ,
调用拷贝的时候在缓存里查找所有的类,判断isMapping是否配置了属性映射, 如果没有就用beanUtil反射。如果有就调用copyProperties方法,copyProperties方法里是根据你的xml映射生成的java属性拷贝代码 。 

cglib没用过的说,不过发现你自从用了cglib就比较喜欢用代理了



纠正一点误区,cglib的功能不仅仅是代理。
你提的思路和我前面提的其中一点优化点是一会事,合并多次的get/set请求生成字节码调用(你可以理解为动态编译成类的属性调用)

BeanMapping的初衷是在保证功能不弱化的前提下,尽可能的优化性能,同时支持良好的扩展性。如果但说性能BeanCopier肯定是最高的,功能也是最simple的,Beanutils功能也是比较好,就是性能有点稍微那个了点。
38 楼 Reset 2011-06-14  
我感觉如果拼速度的话,不如将你的xml映射 动态编译类 ,放到缓存 ,这个类实现某个接口,接口有2个方法,copyProperties(target,dist) ,isMapping(target,dist) ,
调用拷贝的时候在缓存里查找所有的类,判断isMapping是否配置了属性映射, 如果没有就用beanUtil反射。如果有就调用copyProperties方法,copyProperties方法里是根据你的xml映射生成的java属性拷贝代码 。 

cglib没用过的说,不过发现你自从用了cglib就比较喜欢用代理了

37 楼 LSQ6063 2011-06-14  
服务化就是对象转换来转换去很郁闷。。。
36 楼 agapple 2011-06-13  
kimmking 写道
beanutils 有一个比较实用的功能点,就是内部有一系列的converter,
能做到基本类型间的相互转换。

这个比较有用,但是耗性能


恩,不管是多什么样的功能,都会有系统损耗。
在我的测试用例中,没有涉及到类型转化,所以对大家来说都是公平的。

ps: 在我们的BeanMapping中也同样支持类型转化的功能,除此之外还有一些其他的功能,比如defaultValue,script脚本等等
35 楼 kimmking 2011-06-13  
beanutils主要实现了两个功能
1、类型和属性等的工具方法封装
2、动态bean

我多年前做过一个.net版本的beanutils:
http://code.google.com/p/beanutils/
34 楼 kimmking 2011-06-13  
beanutils 有一个比较实用的功能点,就是内部有一系列的converter,
能做到基本类型间的相互转换。

这个比较有用,但是耗性能
33 楼 agapple 2011-06-13  
kimmking 写道
看帖子里的用法和 BeanUtils差不多,
原理是怎么样的,怎么做到比beanutils有数量级的提升?


主要优化了几个点:
1. Method调用转为字节码生成直接调用
2. 减少get/set方法的查找过程,注意好cache设置
3. 合并多次的get/set请求为一次的gets/sets
4. 相比于beanutils,减少了一些无用代码,优化代码的执行顺序,比如beanutils中大量的log.isTraceEnabled(),还有Resolver的执行代码等。

光写个功能实现其实也就只花了我一周的时间,但花了优化和重构上的时间有2周的时间。老实说刚开始的性能还不如Beanutils来的好,都是一点点慢慢提升上来的
32 楼 kimmking 2011-06-13  
看帖子里的用法和 BeanUtils差不多,
原理是怎么样的,怎么做到比beanutils有数量级的提升?
31 楼 agapple 2011-06-13  
wqq686 写道
没看具体实现,楼主可以针对JDK6以上采用Unsafe,如果楼主已经采用了,请忽略。


哈,Unsafe以前只知道是park/unpark,volitale变量处理。 不知道你提的Unsafe它的性能如何?可以说说吗?

可以介绍下,目前BeanMapping的优化实现(之所以可以比Beanutils快那么多),主要还是基于自己码的处理上,合并一些反射调用的处理了

刚才看了下jdk1.6的method.invoke实现,貌似达到一个阀值后也会自行编译为直接码,进行直接调用提升性能。
class NativeMethodAccessorImpl extends MethodAccessorImpl {
   public Object invoke(Object obj, Object[] args)
        throws IllegalArgumentException, InvocationTargetException
    {
        if (++numInvocations > ReflectionFactory.inflationThreshold()) {
            MethodAccessorImpl acc = (MethodAccessorImpl)
                new MethodAccessorGenerator().
                    generateMethod(method.getDeclaringClass(),
                                   method.getName(),
                                   method.getParameterTypes(),
                                   method.getReturnType(),
                                   method.getExceptionTypes(),
                                   method.getModifiers());
            parent.setDelegate(acc);
        }
        
        return invoke0(method, obj, args);
    }
}


阀值的获取: 可以通过环境变量进行设置, -Dsun.reflect.inflationThreshold=15
public class ReflectionFactory {
val = System.getProperty("sun.reflect.inflationThreshold"); // 获取系统变量
                    if (val != null) {
                        try {
                            inflationThreshold = Integer.parseInt(val);
                        } catch (NumberFormatException e) {
                            throw (RuntimeException) 
                                new RuntimeException("Unable to parse property sun.reflect.inflationThreshold").
                                    initCause(e);
                        }
                    }


}


30 楼 agapple 2011-06-13  
yimlin 写道
agapple 写道
yimlin 写道
貌似还不支持父类(抽象定义)+子类继承,遇到相同情况不给搞死,另外父子类存在相同属性怎么处理,貌似会出bug吧。。。。

针对eclipse的重构工具支持给跟上,不然想死的心都有了!


看来是内行人哈,需求记下了。无意中翻到有个类似的工具: dozer。
功能是蛮相似的,但从一些别人介绍中是基于beanutils做的一些扩展,性能上估计存在一些问题。不过它支持的一些功能到是可以参考和实现一下。只是时间的问题


谈不上内行,只是曾经自己想搞一个这样的开源项目,因为种种原因没有实践成,希望你能搞起来。


恩,做这样的事其实就贵在一个坚持。
现在有工作的需求,推进和实施也会有时间上的保障,所以还是比较有谱的,多谢支持哈
29 楼 yimlin 2011-06-13  
agapple 写道
yimlin 写道
貌似还不支持父类(抽象定义)+子类继承,遇到相同情况不给搞死,另外父子类存在相同属性怎么处理,貌似会出bug吧。。。。

针对eclipse的重构工具支持给跟上,不然想死的心都有了!


看来是内行人哈,需求记下了。无意中翻到有个类似的工具: dozer。
功能是蛮相似的,但从一些别人介绍中是基于beanutils做的一些扩展,性能上估计存在一些问题。不过它支持的一些功能到是可以参考和实现一下。只是时间的问题


谈不上内行,只是曾经自己想搞一个这样的开源项目,因为种种原因没有实践成,希望你能搞起来。

相关推荐

Global site tag (gtag.js) - Google Analytics