锁定老帖子 主题:IoC容器的prototype性能测试
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-01-14
to acdc:
大致看了一下joyaop的文档。似乎只能通过ObjectFactory.newInstance()来织入?只能处理构造函数? spring aop都能处理factory method的返回值啊。难道joyaop不能? 另外看了一下aspectwerkz,感觉集成它有点困难。它的aop.xml是封闭的。而且除了aop.xml和annotation,好像也没有提供编程接口来动态配置aspect, interceptor之类的。不知道怎么才能象aspectj那样通过aspectOf来拿到aspect实例,然后给aspect注射依赖? |
|
返回顶楼 | |
发表时间:2006-01-24
ajoo 写道 to acdc:
大致看了一下joyaop的文档。似乎只能通过ObjectFactory.newInstance()来织入?只能处理构造函数? spring aop都能处理factory method的返回值啊。难道joyaop不能? 对在Factory method返回的实例再进行增强,那只能用proxy wrapper,这应该就是为什么Spring 创建BeanProxy这么慢的原因吧? 本来是先天不足的bean instance,要后天去补足(weave advices),性能也只能这样了。 也正是因为想提高性能,我选择了一个折衷的方法,那就是在注册components/beans的时候对bean class进行字节增强处理。这样创建bean的速度大大加快了。 至于容器支持Factory构造的instance,在JADE的最初版本中有支持,但是性能也和Spring一样的坏,至少不会好过用Reflection 创建Proxy这样的效率。 我在后来的重构过程中就去除了对第三方工厂创建的支持,我的理由是,绝大多数情况下工厂模式可以被容器所替代,所以没必要让容器支持第三方工厂,因为容器就是一个通用工厂。如果系统真的需要保留工厂,那就在工厂类实现中把创建实例的任务delegate给容器完成。 还有一点理由就是,使用IoC/Aop绝不是“紧急事后XX”的万灵丹,事实上我认为从架构设计的初期就得开始考虑的这方面的问题。修补和重构那些具有历史遗留问题,尤其是设计方面问题的系统,不是JADE的重点。 JADE和Spring的使用者不一样,它没必要用以大而全的功能去取悦广大开发人员,作者自己一个人爽就够了,弱有人乐意同爽则更好。呵呵。 ajoo 写道 另外看了一下aspectwerkz,感觉集成它有点困难。它的aop.xml是封闭的。而且除了aop.xml和annotation,好像也没有提供编程接口来动态配置aspect, interceptor之类的。不知道怎么才能象aspectj那样通过aspectOf来拿到aspect实例,然后给aspect注射依赖? 一直没空去仔细研究aspectwerkz,但是我想总归有办法的。呵呵。 |
|
返回顶楼 | |
发表时间:2006-01-25
acdc 写道 ajoo 写道 to acdc:
大致看了一下joyaop的文档。似乎只能通过ObjectFactory.newInstance()来织入?只能处理构造函数? spring aop都能处理factory method的返回值啊。难道joyaop不能? 对在Factory method返回的实例再进行增强,那只能用proxy wrapper,这应该就是为什么Spring 创建BeanProxy这么慢的原因吧? 本来是先天不足的bean instance,要后天去补足(weave advices),性能也只能这样了。 也正是因为想提高性能,我选择了一个折衷的方法,那就是在注册components/beans的时候对bean class进行字节增强处理。这样创建bean的速度大大加快了。 至于容器支持Factory构造的instance,在JADE的最初版本中有支持,但是性能也和Spring一样的坏,至少不会好过用Reflection 创建Proxy这样的效率。 我在后来的重构过程中就去除了对第三方工厂创建的支持,我的理由是,绝大多数情况下工厂模式可以被容器所替代,所以没必要让容器支持第三方工厂,因为容器就是一个通用工厂。如果系统真的需要保留工厂,那就在工厂类实现中把创建实例的任务delegate给容器完成。 还有一点理由就是,使用IoC/Aop绝不是“紧急事后XX”的万灵丹,事实上我认为从架构设计的初期就得开始考虑的这方面的问题。修补和重构那些具有历史遗留问题,尤其是设计方面问题的系统,不是JADE的重点。 JADE和Spring的使用者不一样,它没必要用以大而全的功能去取悦广大开发人员,作者自己一个人爽就够了,弱有人乐意同爽则更好。呵呵。 tradeoff。不支持工厂对业务代码就会有侵入性。业务代码要不不许写factory,要不在factory里面调用容器,感觉不爽。 容器的作用和工厂还是不同的,不能完全取代工厂。 为什么不能对构造函数用快的aop,对工厂返回值就用慢的那个呢?有支持总比没有好吧? 对了,你的jade里面,提供了类似declarative transaction的功能么? |
|
返回顶楼 | |
发表时间:2006-01-25
ajoo 写道 tradeoff。不支持工厂对业务代码就会有侵入性。业务代码要不不许写factory,要不在factory里面调用容器,感觉不爽。
容器的作用和工厂还是不同的,不能完全取代工厂。 你说的很对. 先说说我对于微容器嵌入性的看法。 我认为微容器很重要的一个特点是可嵌入性. 所谓的可嵌入性能除了允许在应用系统中用API方式配置容器外,还得允许应用系统方便的"入侵"容器. 要支持这种入侵,同时又不影响原来的容器架构,那么微容器首先得支持父子层次结构, 然后我就可以针对特定的应用系统扩展几个特殊的子容器(类似定制class loader??). 如果要说factory和容器有不同,那么我所能想到的是:factory可能会根据一定的业务逻辑来组装bean. 而现在我通过扩展容器来让这些业务逻辑"入侵"到容器构造bean的过程中. 这样的结果就是:容器就是系统,系统扩展了容器. 要实现这样的功能,容器至少必须有很好的支持层次结构;要有一个良好的bootstrap机制;还要定义好一系列的规则/定义的继承/覆盖规则(尤其是对于那些Pointcut定义的继承合并处理,是我目前碰到的一个有趣的难题)。 ajoo 写道 为什么不能对构造函数用快的aop,对工厂返回值就用慢的那个呢?有支持总比没有好吧? 我想,Reflection创建wrapper bean是动态生成字节码,而这恰恰是最慢的地方,工厂返回值已经是一个instance了,除了构造一个空的wrapper外,我是没有其他更好的办法了。 而用CGLib构造实例就不同,首先它可以cache生成的字节代码,同时,CGLib还可以增加一些HackCode,直接以调用普通方法一样去调用构造函数。这样就肯定比reflection快了,但是这样的方法显然不能用在那些“已经创建”的instance上面。当然,你自己去用CGLib/asm来hack那些bytecode也不是没有可能的。 ajoo 写道 对了,你的jade里面,提供了类似declarative transaction的功能么? Sure, 我抽象了一个SessionManager interface,然后一个简单的TxInterceptor。目前可以支持Hibernate/iBatis。按照上面的父子容器特性,我可以在顶级容器配置TxInterceptor,而在不同的容器使用不同的SessionManager implementation,虽然对于DAO library,需要这样使用的可能性几乎为0 |
|
返回顶楼 | |
发表时间:2006-01-27
acdc 写道 ajoo 写道 tradeoff。不支持工厂对业务代码就会有侵入性。业务代码要不不许写factory,要不在factory里面调用容器,感觉不爽。
容器的作用和工厂还是不同的,不能完全取代工厂。 你说的很对. 先说说我对于微容器嵌入性的看法。 我认为微容器很重要的一个特点是可嵌入性. 所谓的可嵌入性能除了允许在应用系统中用API方式配置容器外,还得允许应用系统方便的"入侵"容器. 要支持这种入侵,同时又不影响原来的容器架构,那么微容器首先得支持父子层次结构, 然后我就可以针对特定的应用系统扩展几个特殊的子容器(类似定制class loader??). 如果要说factory和容器有不同,那么我所能想到的是:factory可能会根据一定的业务逻辑来组装bean. 而现在我通过扩展容器来让这些业务逻辑"入侵"到容器构造bean的过程中. 这样的结果就是:容器就是系统,系统扩展了容器. 要实现这样的功能,容器至少必须有很好的支持层次结构;要有一个良好的bootstrap机制;还要定义好一系列的规则/定义的继承/覆盖规则(尤其是对于那些Pointcut定义的继承合并处理,是我目前碰到的一个有趣的难题)。 我不是很明白你的“组件入侵容器”的概念。或者说,它是不是“容器入侵性”的一种更好听的说法? 我一直认为,组件就是要能够在不同的容器,或者在容器外面跑,才叫作真正的轻量级设计。象acegi那样死死绑在spring上的,就不是轻量级的。 不知道你提到的这种入侵容器,是否会对组件的可移植性造成影响。 父子容器基本上现在的容器产品都支持的,算是基本功能了吧? 关于factory,其实做api的,很多时候会弄出工厂方法来,比如DateFormat.getInstance(),比如aspectOf()。这种工厂主要是组件自己主动要封装隐藏实现细节的产物,算是应用领域的逻辑。容器在infrastructure的层面上对组件指手画脚,说你不应该用工厂,要用我代替工厂,我觉得不好。 |
|
返回顶楼 | |
发表时间:2006-01-27
ajoo 写道 我不是很明白你的“组件入侵容器”的概念。或者说,它是不是“容器入侵性”的一种更好听的说法? 我一直认为,组件就是要能够在不同的容器,或者在容器外面跑,才叫作真正的轻量级设计。象acegi那样死死绑在spring上的,就不是轻量级的。 的确,应用系统的开发者必须得为该容器提供一个自己的“扩展包”。事实上,我们在使用Spring的时候,也一定会调用它的一些API去配置Spring,我觉得这两个问题在本质上是一致的。所以,哪怕“扩展”是如此的简单,那么它一定是有入侵性得。从这个角度来看,只要容器有可嵌入特性,那么所谓的入侵问题肯定存在的。更甚,只要容器提供配置文件,那就要算入侵,因为当你从Spring移植到Nuts,配置文件不是要重写?对一个巨大的系统,这个移植绝对比写代码还痛苦,这还能算自由迁移么? ajoo 写道 不知道你提到的这种入侵容器,是否会对组件的可移植性造成影响。 肯定有影响啊。上面也提到了,除了配置文件不兼容,还有其他方面的兼容问题。因为没有一个标准阿。只有一个JADE这么做,每个框架都自己做自己的。 扯远点说,市场上不同Servlet容器之间还存在移植问题呢。呵呵。 所以,零入侵性只能是一个遥远的梦想阿。 ajoo 写道 父子容器基本上现在的容器产品都支持的,算是基本功能了吧?
我好像还没看到哪个AOP framework的配置是可以支持继承重用的 |
|
返回顶楼 | |
发表时间:2006-01-27
acdc 写道 ajoo 写道 我不是很明白你的“组件入侵容器”的概念。或者说,它是不是“容器入侵性”的一种更好听的说法? 我一直认为,组件就是要能够在不同的容器,或者在容器外面跑,才叫作真正的轻量级设计。象acegi那样死死绑在spring上的,就不是轻量级的。 的确,应用系统的开发者必须得为该容器提供一个自己的“扩展包”。事实上,我们在使用Spring的时候,也一定会调用它的一些API去配置Spring,我觉得这两个问题在本质上是一致的。所以,哪怕“扩展”是如此的简单,那么它一定是有入侵性得。从这个角度来看,只要容器有可嵌入特性,那么所谓的入侵问题肯定存在的。更甚,只要容器提供配置文件,那就要算入侵,因为当你从Spring移植到Nuts,配置文件不是要重写?对一个巨大的系统,这个移植绝对比写代码还痛苦,这还能算自由迁移么? 这个么。。。 我怎么感觉象是说人都是要死的,所以杀人无罪呢? 我说的是组件的移植性,而不是整个系统包括infrastructre的移植性。 换句话说,我写组件,只要组件本身不依赖容器,那么自然可以自由迁移。至于容器给我提供的一些service本来就是免费的,我又没有花费任何代价,谈什么“移植”?扩展包虽然不能移植,但是这种扩展往往代价很小,比较trivial。(即使逻辑复杂,但是和容器接口部分也可以很薄,大量的逻辑还是可以抽出来组成不依赖容器的,可移植的功能模块) 当然,配置文件(或者大而化之,deployment descriptor),总是要重写(或者通过工具转换),不过,配置文件比写代码痛苦?有点耸人听闻了吧?虽然spring的配置文件比较恶,也应该没到这种程度。更不要说Nuts的配置文件。 还有,扩展,也看怎么扩展。Spring那样动不动就靠让组件实现ApplicationContextAware接口来搞所谓“扩展”,自然影响移植性。但是如果能始终保持组件的pojo本质,那么扩展也不影响移植性。 acdc 写道 ajoo 写道 不知道你提到的这种入侵容器,是否会对组件的可移植性造成影响。 肯定有影响啊。上面也提到了,除了配置文件不兼容,还有其他方面的兼容问题。因为没有一个标准阿。只有一个JADE这么做,每个框架都自己做自己的。 扯远点说,市场上不同Servlet容器之间还存在移植问题呢。呵呵。 所以,零入侵性只能是一个遥远的梦想阿。 配置文件不算,因为它是infrastructure的一部分,组件可以根本不理配置文件这码事。还有其它的什么兼容问题? 零侵入是梦么?至少业务组件的零侵入不是。 acdc 写道 ajoo 写道 父子容器基本上现在的容器产品都支持的,算是基本功能了吧?
我好像还没看到哪个AOP framework的配置是可以支持继承重用的 aop的重用为什么非要依赖父子容器?这不是两个范畴的正交的概念?不需要互相耦合吧? |
|
返回顶楼 | |