网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  aspectj: 通往aosd之路的最佳军火     
  文章作者:未知  文章来源:水木森林  
  查看:69次  录入:管理员--2007-11-17  
 

同步自:http://www.blogjava.net/anderslin/archive/2006/06/24/54806.html

在aosd:应用aop实现业务逻辑中, 我提出关注的接口;
其原文在javaeye上的讨论狼平方也提出可以用event,或者intercepter。
当然不同的方式可以解决不同的问题。这里要讨论一下aspectj和event以及intercepter的不同。

1. 先来看看event的方式:需要两个对象event和eventhandler(eventlistener),event和eventhandler,属于数据契约。换句话说,牺牲了编译检查的好处,当然可以应对变化时有一定的好处。一旦需求变化,代码上的变动需要的工作量不少,更为严重的是,如狼平方所说的侵入性太强。
2  接着看interceptor的aop,相对于event方式,虽然都是基于数据契约,都给自己做转型,但是代码量少了(因为代码生成),重要的是没有event那样的侵入性。
3. 狼平方做了改进,利用aop来做brocastevent的工作。需要做的工作还是很多,甚至我以为这个工作还不如直接用interceptor来得直接。

    如我在小议领域模型(domain model) 所说的domain service处理两个逻辑:业务规则和流程逻辑,而aosd:应用aop实现业务逻辑要试图解决的问题是流程上逻辑,而以上无论是那种方式,都无法解决一个问题:流程信息。
假定现有两个流程如下:

aspectj: 通往aosd之路的最佳军火(图一) aspectj: 通往aosd之路的最佳军火(图二) public   class  domainservice  aspectj: 通往aosd之路的最佳军火(图三) {
aspectj: 通往aosd之路的最佳军火(图四)aspectj: 通往aosd之路的最佳军火(图五)     public   void  bizprocessa() aspectj: 通往aosd之路的最佳军火(图三) {
aspectj: 通往aosd之路的最佳军火(图六)        aspectj: 通往aosd之路的最佳军火(图三)
aspectj: 通往aosd之路的最佳军火(图六)        someobject instance  =  dosomeaction(aspectj: 通往aosd之路的最佳军火(图三));
aspectj: 通往aosd之路的最佳军火(图六)        aspectj: 通往aosd之路的最佳军火(图三)
aspectj: 通往aosd之路的最佳军火(图七)    }
aspectj: 通往aosd之路的最佳军火(图六)
aspectj: 通往aosd之路的最佳军火(图四) aspectj: 通往aosd之路的最佳军火(图五)     public   void  bizprocessb() aspectj: 通往aosd之路的最佳军火(图三) {
aspectj: 通往aosd之路的最佳军火(图六)        aspectj: 通往aosd之路的最佳军火(图三)
aspectj: 通往aosd之路的最佳军火(图六)        someobject instance  =  dosomeaction(aspectj: 通往aosd之路的最佳军火(图三));
aspectj: 通往aosd之路的最佳军火(图六)        aspectj: 通往aosd之路的最佳军火(图三)
aspectj: 通往aosd之路的最佳军火(图七)    }
aspectj: 通往aosd之路的最佳军火(图四) aspectj: 通往aosd之路的最佳军火(图五)     public  someobject dosomeaction(aspectj: 通往aosd之路的最佳军火(图三)) aspectj: 通往aosd之路的最佳军火(图三) {
aspectj: 通往aosd之路的最佳军火(图六)        aspectj: 通往aosd之路的最佳军火(图三)
aspectj: 通往aosd之路的最佳军火(图七)    }
aspectj: 通往aosd之路的最佳军火(图八)}

这里我们关注的目标方法是dosomeaction(),在dosomeaction中我们希望做些额外的工作,
以狼平方的例子,比如:financialservice.createrequestofmoney(...);
那么无论是用event:

aspectj: 通往aosd之路的最佳军火(图一) aspectj: 通往aosd之路的最佳军火(图二) public  someobject dosomeaction(aspectj: 通往aosd之路的最佳军火(图三)) aspectj: 通往aosd之路的最佳军火(图三) {
aspectj: 通往aosd之路的最佳军火(图六) aspectj: 通往aosd之路的最佳军火(图三)
aspectj: 通往aosd之路的最佳军火(图六) brocastevent( new  event(aspectj: 通往aosd之路的最佳军火(图三)));
aspectj: 通往aosd之路的最佳军火(图八)}

还是interceptor:

aspectj: 通往aosd之路的最佳军火(图一) aspectj: 通往aosd之路的最佳军火(图二) public   class  someinterceptor  implements  methodinterceptor   aspectj: 通往aosd之路的最佳军火(图三) {
aspectj: 通往aosd之路的最佳军火(图四)aspectj: 通往aosd之路的最佳军火(图五)     public  object invoke(methodinvocation invoke)  aspectj: 通往aosd之路的最佳军火(图三) {
aspectj: 通往aosd之路的最佳军火(图六)          obj  =  invoke.proceed(); //  执行被拦截的方法完成业务操作       
aspectj: 通往aosd之路的最佳军火(图六)         aspectj: 通往aosd之路的最佳军火(图三).
aspectj: 通往aosd之路的最佳军火(图六)         financialservice.createrequestofmoney(aspectj: 通往aosd之路的最佳军火(图三).);
aspectj: 通往aosd之路的最佳军火(图七)    }
aspectj: 通往aosd之路的最佳军火(图八)}

我们注意到,这样做的结果是在bizprocessa()和bizprocessb()的不同业务流程都将导致执行
financialservice.createrequestofmoney
不过我们的流程逻辑要求是:
在bizprocessa()的流程下,执行financialservice.createrequestofmoney
而在bizprocessb的流程下,不执行financialservice.createrequestofmoney。

很明显无论是之上event,还是interceptor的aop都无法解决这个问题。

面对这样的需求,就需要改进或者重构:
1. 最简单也最直接改dosomeaction(...)为dosomeaction(...boolean flag)。很明显这样的做法很不理想
2. 来点oo的, 将dosomeaction(...)分出去,作为一个接口,采用多态解决。不过依然需要解决动态加载问题,处理起来又需要费点手段。

真的只有这两个手段了吗?不!还有,那就是aspectj
aspectj提供了如下
within
withincode
withincode
cflow
cflowbelow

几个内置的pointcut,将可以做到我们要的效果,代码如下:

aspectj: 通往aosd之路的最佳军火(图一) aspectj: 通往aosd之路的最佳军火(图二) public  aspect serviceaspect aspectj: 通往aosd之路的最佳军火(图三) {
aspectj: 通往aosd之路的最佳军火(图六) pointcut bp(): cflow(call( void  domainservice.bizprocessa(..)));
aspectj: 通往aosd之路的最佳军火(图六) pointcut action(): call(dosomeaction(aspectj: 通往aosd之路的最佳军火(图三)));
aspectj: 通往aosd之路的最佳军火(图六)
aspectj: 通往aosd之路的最佳军火(图四)aspectj: 通往aosd之路的最佳军火(图五) someobject around(aspectj: 通往aosd之路的最佳军火(图三)) : bp()  &&  action()  &&  args(aspectj: 通往aosd之路的最佳军火(图三)) aspectj: 通往aosd之路的最佳军火(图三) {
aspectj: 通往aosd之路的最佳军火(图六)  someobject instance  =  proceed(aspectj: 通往aosd之路的最佳军火(图三));
aspectj: 通往aosd之路的最佳军火(图六)  financialservice.createrequestofmoney(aspectj: 通往aosd之路的最佳军火(图三).);
aspectj: 通往aosd之路的最佳军火(图六)   return  instance;
aspectj: 通往aosd之路的最佳军火(图七) }
aspectj: 通往aosd之路的最佳军火(图八)}

很显然,aspectj提供了aosd所需要的军火。

btw:本文不针对狼平方同学,只是借由其两篇blog讨论开来,解释了aspectj优点,以及为什么aspectj是实现aosd的最佳也是唯一军火。
事实上很多时候,解决问题的方法有很多,本文旨在阐明aosd为我们提供了另一条思路。欢迎讨论和拍砖!

另补上我在javaeye讨论贴的完整例子代码,下载

 
 
上一篇: 在目录中查找类位于哪个jar包中    下一篇: javase 6基于jsr105的xml签名之理论篇
  相关文档
何种设计模式和构架才能开发出最好的企业程序 11-17
java编程思想读书笔记(第5-7章)二 11-17
基于jsf技术的web应用开发研究 11-17
jbuilder制作音频播放程序 11-16
成学人生:java开发真的需要那么复杂吗? 11-16
gef-all-3.1 11-17
java 库的建立方法及其实例(2) 11-17
java对domino objects的访问 (3) 11-17
java-如何实现timer功能 11-17
使用缓冲提高输入/输出的性能 11-17
java教程 第八讲 java网络编程 11-17
新手入门:j2ee学习经验和流程 11-17
apache 1.3.14主要变化 11-17
jsp/servlet:easyjweb中文件上传的处理 01-25
平行世界:java和xml为何将成功 11-17
scjp认证套题解析之十一 11-16
在java应用程序中监视cpu的使用 11-17
用eclipse visual editor 开发swt gui 11-17
阴阳历算法(转) 11-17
java 理论与实践: web 层的状态复制 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
厦门(总部):13616026886 福州:0591-87655121
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息