论坛首页 Java企业应用论坛

IoC容器的prototype性能测试

浏览 23778 次
该帖已经被评为精华帖
作者 正文
   发表时间: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注射依赖?
0 请登录后投票
   发表时间: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,但是我想总归有办法的。呵呵。
0 请登录后投票
   发表时间: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的功能么?
0 请登录后投票
   发表时间: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
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的层面上对组件指手画脚,说你不应该用工厂,要用我代替工厂,我觉得不好。
0 请登录后投票
   发表时间:2006-01-27  
ajoo 写道

我不是很明白你的“组件入侵容器”的概念。或者说,它是不是“容器入侵性”的一种更好听的说法?
我一直认为,组件就是要能够在不同的容器,或者在容器外面跑,才叫作真正的轻量级设计。象acegi那样死死绑在spring上的,就不是轻量级的。


的确,应用系统的开发者必须得为该容器提供一个自己的“扩展包”。事实上,我们在使用Spring的时候,也一定会调用它的一些API去配置Spring,我觉得这两个问题在本质上是一致的。所以,哪怕“扩展”是如此的简单,那么它一定是有入侵性得。从这个角度来看,只要容器有可嵌入特性,那么所谓的入侵问题肯定存在的。更甚,只要容器提供配置文件,那就要算入侵,因为当你从Spring移植到Nuts,配置文件不是要重写?对一个巨大的系统,这个移植绝对比写代码还痛苦,这还能算自由迁移么?


ajoo 写道

不知道你提到的这种入侵容器,是否会对组件的可移植性造成影响。

肯定有影响啊。上面也提到了,除了配置文件不兼容,还有其他方面的兼容问题。因为没有一个标准阿。只有一个JADE这么做,每个框架都自己做自己的。
扯远点说,市场上不同Servlet容器之间还存在移植问题呢。呵呵。
所以,零入侵性只能是一个遥远的梦想阿。

ajoo 写道
父子容器基本上现在的容器产品都支持的,算是基本功能了吧?

我好像还没看到哪个AOP framework的配置是可以支持继承重用的
0 请登录后投票
   发表时间: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的重用为什么非要依赖父子容器?这不是两个范畴的正交的概念?不需要互相耦合吧?
0 请登录后投票
论坛首页 Java企业应用版

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