浏览 5725 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-01-23
引用 this - limits matching to join points (the execution of methods when using Spring AOP) where the bean
reference (Spring AOP proxy) is an instance of the given type • target - limits matching to join points (the execution of methods when using Spring AOP) where the target object (application object being proxied) is an instance of the given type 似乎看不出两者的具体区别,我试着做了一个测试: 切面定义类: package com.baobaotao.expression; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class PreGreetingAspect{ @Before("target(com.baobaotao.expression.NaiveWaiter)") public void beforeGreeting(){ System.out.println("How are you"); } } 目标类接口: package com.baobaotao.expression; public interface Waiter { public void greetTo(String name); public void serveTo(String name); } 目标接口实现类: package com.baobaotao.expression; public class NaiveWaiter implements Waiter { public void greetTo(String name) { System.out.println("greet to "+name+"..."); } public void serveTo(String name){ System.out.println("serving "+name+"..."); foo(name); } public void foo(String name){ System.out.println("foo "+name+"..."); } } 然后是配置: <aop:aspectj-autoproxy /> <bean id="waiter" class="com.baobaotao.expression.NaiveWaiter" /> <bean id="greetingAfter" class="com.baobaotao.expression.PreGreetingAspect" /> 最后是测试: package com.baobaotao.expression; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.baobaotao.expression.Waiter; public class TestExpression { public static void main(String[] args) { String configPath = "com/baobaotao/expression/beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); Waiter waiter = (Waiter)ctx.getBean("waiter"); waiter.greetTo("John"); waiter.serveTo("John"); } } 输出以下信息: How are you greet to John... How are you serving John... 将切点定义换成: @Before("this(com.baobaotao.expression.Waiter)") 输出的效果是完全一样的。 我的分析: 我本来以为NaiveWaiter的foo()方法在使用@Before("target(com.baobaotao.expression.NaiveWaiter)")应该也可以织入切面,但是发现不管采用哪种方式只能为Waiter接口织入切面。 请问这两个切点表示符到底有什么区别,我现在看到的是两者好象完全一样。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-01-23
this标示调用方,target标示被调用方.
|
|
返回顶楼 | |
发表时间:2007-01-23
谢谢partech是回答
partech 写道 this标示调用方,target标示被调用方.
可是,象我的例子中Waiter是引用类型,而NaiveWaiter是被调用类型,但以下四种方式定义的切面效果都是一样的: @Before("target(com.baobaotao.expression.NaiveWaiter)") @Before("target(com.baobaotao.expression.Waiter)") @Before("this(com.baobaotao.expression.NaiveWaiter)") @Before("this(com.baobaotao.expression.Waiter)") 不知道this和target究竟应用场合有什么区别,我们怎么看到它们不同的效果? |
|
返回顶楼 | |
发表时间:2007-01-23
this和target通常用来限定切点的作用域,单独使用,俺想不出场景,你在pointcut上加个call试一下。
|
|
返回顶楼 | |
发表时间:2007-01-23
越分析,越觉得两者越没有区别,假设我有二个类,他们分别实现一个接口:
Waiter |_NaiveWaiter |_NaughtWaiter 我以下的切点定义都是等效的: this(Waiter) <==> target(Waiter) <==> target(NaiveWaiter) || target(NaughtWaiter) <==> this(NaiveWaiter) || this(NaughtWaiter) Spring中配置的: 引用 <bean id="waiter1" class="com.baobaotao.expression.NaiveWaiter" /> <bean id="waiter2" class="com.baobaotao.expression.NaughtyWaiter" /> 这两个Bean的方法都会被代理。 我都快要疯了 ,难道真的没有区别吗?应该是不会的,可是到底如何分辨呢,难,难,难! |
|
返回顶楼 | |
发表时间:2007-01-23
目前我的结论是:this这个切点标识符是Spring的一个Bug。开发文档上说this用于指定代理对象的类型,而实际上它用于指示代理目标类的类型,所以完全和target一样了。这是我的实验结果,不知道大家有何高见。
|
|
返回顶楼 | |
发表时间:2007-01-23
是不是spring的bug,我就不清楚了。
附件是直接使用aspectj的验证。 输出: C1.f1 before thisC1PointCut before targetC2PointCut C2.f1 |
|
返回顶楼 | |
发表时间:2007-01-23
TMD,终于搞定了,是这样的:
@Before"this(com.baobaotao.Seller)" void test(){} 表示这样的情况,某个目标类如 NaiveWaiter所生成的代理对象是Seller类型,则NaiveWaiter上的所有方法织入test()方法,这种情况一般用于引入增强的情况,引入可以为目标类添加某一个接口的实现,如: package com.baobaotao.expression; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.DeclareParents; @Aspect public class PreGreetingAspect { @DeclareParents(value = "com.baobaotao.expression.*", defaultImpl = GoodSeller.class) public static Seller seller; @Before(" execution(* greetTo(..)) && this(com.baobaotao.expression.Seller)") public void recordUsage() { System.out.println("Haha"); } } 为com.baobaotao.expression包下的所有类引入Seller接口的实现,这样代理对象就都是Seller类型了,因此 @Before(" execution(* greetTo(..)) && this(com.baobaotao.expression.Seller)")匹配目标类的所有greetTo()方法,这里,要是我们把它改为: @Before(" execution(* greetTo(..)) && target(com.baobaotao.expression.Seller)") 目标类的greetTo()方法就得不到增强了。 |
|
返回顶楼 | |