论坛首页 Java企业应用论坛

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

浏览 25049 次
该帖已经被评为良好帖
作者 正文
   发表时间:2011-06-13  
yimlin 写道
agapple 写道
yimlin 写道
貌似还不支持父类(抽象定义)+子类继承,遇到相同情况不给搞死,另外父子类存在相同属性怎么处理,貌似会出bug吧。。。。

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


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


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


恩,做这样的事其实就贵在一个坚持。
现在有工作的需求,推进和实施也会有时间上的保障,所以还是比较有谱的,多谢支持哈
0 请登录后投票
   发表时间: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);
                        }
                    }


}


0 请登录后投票
   发表时间:2011-06-13  
看帖子里的用法和 BeanUtils差不多,
原理是怎么样的,怎么做到比beanutils有数量级的提升?
0 请登录后投票
   发表时间: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来的好,都是一点点慢慢提升上来的
0 请登录后投票
   发表时间:2011-06-13  
beanutils 有一个比较实用的功能点,就是内部有一系列的converter,
能做到基本类型间的相互转换。

这个比较有用,但是耗性能
0 请登录后投票
   发表时间:2011-06-13  
beanutils主要实现了两个功能
1、类型和属性等的工具方法封装
2、动态bean

我多年前做过一个.net版本的beanutils:
http://code.google.com/p/beanutils/
0 请登录后投票
   发表时间:2011-06-13  
kimmking 写道
beanutils 有一个比较实用的功能点,就是内部有一系列的converter,
能做到基本类型间的相互转换。

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


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

ps: 在我们的BeanMapping中也同样支持类型转化的功能,除此之外还有一些其他的功能,比如defaultValue,script脚本等等
0 请登录后投票
   发表时间:2011-06-14  
服务化就是对象转换来转换去很郁闷。。。
0 请登录后投票
   发表时间:2011-06-14  
我感觉如果拼速度的话,不如将你的xml映射 动态编译类 ,放到缓存 ,这个类实现某个接口,接口有2个方法,copyProperties(target,dist) ,isMapping(target,dist) ,
调用拷贝的时候在缓存里查找所有的类,判断isMapping是否配置了属性映射, 如果没有就用beanUtil反射。如果有就调用copyProperties方法,copyProperties方法里是根据你的xml映射生成的java属性拷贝代码 。 

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

0 请登录后投票
   发表时间: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功能也是比较好,就是性能有点稍微那个了点。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics