论坛首页 Java企业应用论坛

我的酒窝

浏览 43500 次
锁定老帖子 主题:我的酒窝
该帖已经被评为精华帖
作者 正文
   发表时间:2006-12-22  
floating 写道
我给出的场景一的代码并不是拦截了项目中所有的prepareStatement调用。通过修改aspectj的inpath属性可以指定拦截任意路径下的代码(比如所有单元测试代码所在路径)。

ajoo 写道

场景二:用within也不管用啊。我又不是想全局性拦截untrustedFunction。untrustedFunction被在若干个地方调用。而其它地方的代码在它close connection的时候都工作的很好,我并不清楚贸然禁止它调用Connection.close()到底是福是祸。我知道的是我的模块想要自己控制connection,所以需要局部地架空Connection.close。


这个和上面的那个问题也可以用同样的方式解决。至于aspectj的适用范围的问题,我在上次的回帖中已经说了,aspectj已经将aop的复杂性屏蔽的很好了,需要补充的是,aop其实也挺适合用来做单元测试的工作的,至少是对它的一个有益的补充。具体的文章可以看看developerWorks上的相关文章。里面有几篇就是和单元测试相关的。


场景一不是拦截的问题,是我需要一个Connection对象的问题。我从哪里得到这个Connection对象?没有对象我怎么调用prepareStatement?没有我调用prepareStatement,aspectj拦截个啥?
所以我才问你要一个示例客户代码或者测试代码,你说很简单,但是就不肯写出来。于是就姑且认为你不懂什么叫stub测试了。

场景二也不是制定某个路径就可以的,我需要的是对“某一个Connection实例”的decorate,不是不分青红皂白的拦截。比如:
realConn = ...;
nonCloseable = decorate(realConn);
nonCloseable.close();//被拦截
realConn.close();//不被拦截

这些代码可能都在一个类里面的(或者在两个类里面,具体在哪里我不关心)。这怎么“轻易”地用aspectj实现?
0 请登录后投票
   发表时间:2006-12-22  
ajoo 写道

场景一不是拦截的问题,是我需要一个Connection对象的问题。我从哪里得到这个Connection对象?没有对象我怎么调用prepareStatement?没有我调用prepareStatement,aspectj拦截个啥?

我先说明一个问题,怎么在代码里判断一个Connection实例是不是需要进行处理的实例?无非两个方法,一个是根据调用Connection的代码路径来判断,另一种就是需要根据运行期的上下文环境来判断。但是大多数情况根据代码路径判断就足够了。如果楼主的意思是必须根据运行期的上下文来判断才足够的话,目前aspectJ的确还不能做到很直观的支持(因为aspectJ目前还不支持纯粹的runtime织入,这是aspectJ发展的一个方向)。
ajoo 写道

所以我才问你要一个示例客户代码或者测试代码,你说很简单,但是就不肯写出来。于是就姑且认为你不懂什么叫stub测试了。

楼主大概没看清楚我的回帖,我并不是说很简单,而是说因为aspectJ目前的织入方式是编译期织入或者classloading织入,所以并没有楼主所谓的客户代码。

ajoo 写道

场景二也不是制定某个路径就可以的,我需要的是对“某一个Connection实例”的decorate,不是不分青红皂白的拦截。比如:
realConn = ...;
nonCloseable = decorate(realConn);
nonCloseable.close();//被拦截
realConn.close();//不被拦截

这些代码可能都在一个类里面的(或者在两个类里面,具体在哪里我不关心)。这怎么“轻易”地用aspectj实现?

结合这个例子我觉得更能说明一个问题。就是aspectJ(AOP)对开发人员的思维习惯是有比较大的影响的。比如上例中我就会这样写:
public void untrustFunction()
{
   realConn = ....;
   realConn.close();
}
public void trustFunction()
{
   realConn = ...;
   realConn.close();
}


我猜测楼主可能有些误解,pointcut针对的是方法或者属性操作(getter,setter),并不是针对类。所以,只要能明确代码中哪些方法是我们不信任的就可以产生出这个切面。其实,我想像不出什么样的场景下,在同一个方法中,对于来自同一个对象的两个实例,一个是信任的,一个是不信任的。

再强调一下,aspectJ既然是面向方面,那当然是针对具有共性的操作,也就是说能够产生这样一个横向的切面(无论这个切面是动态的还是静态的)。这是使用AOP技术的前提,如果这个前提都不存在,那自然就不应该使用AOP技术。回顾一下,楼主的帖子刚开始描述的场景,我起初认为还是具有很强的共性的。随着讨论的深入,楼主举的例子越来越不具有这种共性(很可能是我理解能力差,楼主最开始的例子也是想说一个不具有共性的情况),在这种情况下,即使用aspectJ的确能解决问题,也是完全没有必要的。

至于怎么用AOP的技术进行单元测试,在developerWorks上面有一篇比较详细的文章可以参考。
http://www.ibm.com/developerworks/cn/java/j-aspectj2/
0 请登录后投票
   发表时间:2006-12-22  
  现在有一个接口Connection,只需要close这个方法,其他的都不需要,dimple用dynamic proxy把一个oobject代理成Connection,这样就可以使用close了。
  aop可以拦截方法调用,如果是一个现成的Connection,那没有问题,问题是,现在没有一个Connection,aop拦截什么?mixin的话,也是需要cglib增强的吧
0 请登录后投票
   发表时间:2006-12-22  
floating 写道

ajoo 写道

场景二也不是制定某个路径就可以的,我需要的是对“某一个Connection实例”的decorate,不是不分青红皂白的拦截。比如:
realConn = ...;
nonCloseable = decorate(realConn);
nonCloseable.close();//被拦截
realConn.close();//不被拦截

这些代码可能都在一个类里面的(或者在两个类里面,具体在哪里我不关心)。这怎么“轻易”地用aspectj实现?

结合这个例子我觉得更能说明一个问题。就是aspectJ(AOP)对开发人员的思维习惯是有比较大的影响的。比如上例中我就会这样写:
public void untrustFunction()
{
   realConn = ....;
   realConn.close();
}
public void trustFunction()
{
   realConn = ...;
   realConn.close();
}


我猜测楼主可能有些误解,pointcut针对的是方法或者属性操作(getter,setter),并不是针对类。所以,只要能明确代码中哪些方法是我们不信任的就可以产生出这个切面。其实,我想像不出什么样的场景下,在同一个方法中,对于来自同一个对象的两个实例,一个是信任的,一个是不信任的。

再强调一下,aspectJ既然是面向方面,那当然是针对具有共性的操作,也就是说能够产生这样一个横向的切面(无论这个切面是动态的还是静态的)。这是使用AOP技术的前提,如果这个前提都不存在,那自然就不应该使用AOP技术。回顾一下,楼主的帖子刚开始描述的场景,我起初认为还是具有很强的共性的。随着讨论的深入,楼主举的例子越来越不具有这种共性(很可能是我理解能力差,楼主最开始的例子也是想说一个不具有共性的情况),在这种情况下,即使用aspectJ的确能解决问题,也是完全没有必要的。

至于怎么用AOP的技术进行单元测试,在developerWorks上面有一篇比较详细的文章可以参考。
http://www.ibm.com/developerworks/cn/java/j-aspectj2/

场景一我就不说了。别人也都解释了。
对场景二,我要说的是:工具就老老实实当工具。你这里试图让我相信aspectj可以解决这个问题。但是通过交流下来,我没有发现aspectj在解决这个问题方面有什么好处,只是通过你逐渐地吞吞吐吐中发现aspectj先要对我的编程方式提出很多的要求。比如说必须按照aop的思想方法去思考和编码才成。我把这看成一个侵入,或者是aspectj的无能。

我们应该根据需要合理选择工具,而不是为了使用某个工具先强迫别人使用某种风格。场景二从一开始就是一个模块内部的实现细节,通过强迫这个模块地实现遵循某个切面原则破坏了封装,增加了系统的复杂度。老实说如果aspectj要这样使用,那对我这样在aop门外徘徊的人来说就太可怕了。

0 请登录后投票
   发表时间:2006-12-23  
ajoo 写道

对场景二,我要说的是:工具就老老实实当工具。你这里试图让我相信aspectj可以解决这个问题。但是通过交流下来,我没有发现aspectj在解决这个问题方面有什么好处,只是通过你逐渐地吞吞吐吐中发现aspectj先要对我的编程方式提出很多的要求。比如说必须按照aop的思想方法去思考和编码才成。我把这看成一个侵入,或者是aspectj的无能。

这倒不是我有意吞吞吐吐,因为我看过楼主做的一些东西,刚开始不知道楼主这样的高手对aop的代表产物aspectj了解的这么少。至于一种思维方式算不算一种侵入,这大概是仁者见仁智者见智的问题。比如楼主经常提到的各种模式也可以看成一种思维方式,那算不算侵入呢?可能楼主会说没有人强迫你非要用什么模式,aop也一样的,没有人强迫你非要用aop的方式编程,只是在很多情况下,采用一点aop可以达到事半功倍的效果。更何况,aop代表了java开发技术的一个方向,对它视而不见不是一个程序员应有的素质。

ajoo 写道

场景二从一开始就是一个模块内部的实现细节,通过强迫这个模块地实现遵循某个切面原则破坏了封装,增加了系统的复杂度。

对于场景二,我应该承认是我理解的错误。如果这个场景不具有共性,那么采用aop的方式的确是由大炮打蚊子的讽刺效果。呵呵。
0 请登录后投票
   发表时间:2007-01-04  
# Use @Implement annotation to automatically verify the method signature against the method being implemented.

看单元测试,这个@Implement只能做到运行期检查是不是接口里存在该方法,能做成编译期检查不是更好?

期待!
0 请登录后投票
   发表时间:2007-01-04  
以我对annotation的了解,还不知道怎么能够定制编译期检查。java5有这个功能么?
0 请登录后投票
   发表时间:2007-01-04  
我也不知道,那3个基本的编译期annotation怎么实现的?


e.g @override
0 请登录后投票
   发表时间:2007-01-04  
alin_ass 写道
我也不知道,那3个基本的编译期annotation怎么实现的?


e.g @override

怀疑是Sun在编译器内部特制的。
0 请登录后投票
   发表时间:2007-01-04  
用你这个取代mock类,万一接口方法名变了,重构挺麻烦的
0 请登录后投票
论坛首页 Java企业应用版

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