`

谁能说说@AspectJ中this和target这两个切点标识符的具体区别

阅读更多
   Spring Reference对这两个切点标识符的用法描述得不太清楚:
引用
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接口织入切面。
   请问这两个切点表示符到底有什么区别,我现在看到的是两者好象完全一样。

分享到:
评论
10 楼 duckCaptain 2013-06-07  
那个引入的也是这两个东西的不同之一。:D
9 楼 duckCaptain 2013-06-07  
不知道是不是新版本的改进,在3.2 中,
@Before("this(main.com.fqs.differ.NaiveWaiter)")
是不会被代理的
而使用
@Before("target(main.com.fqs.differ.NaiveWaiter)")
是可以被代理的
8 楼 bzssyks 2007-06-19  
顶楼主~~~
7 楼 stamen 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()方法就得不到增强了。
6 楼 partech 2007-01-23  
是不是spring的bug,我就不清楚了。
附件是直接使用aspectj的验证。
输出:
C1.f1
before thisC1PointCut
before targetC2PointCut
C2.f1
5 楼 stamen 2007-01-23  
目前我的结论是:this这个切点标识符是Spring的一个Bug。开发文档上说this用于指定代理对象的类型,而实际上它用于指示代理目标类的类型,所以完全和target一样了。这是我的实验结果,不知道大家有何高见。
4 楼 stamen 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的方法都会被代理。

   我都快要疯了  ,难道真的没有区别吗?应该是不会的,可是到底如何分辨呢,难,难,难!
3 楼 partech 2007-01-23  
this和target通常用来限定切点的作用域,单独使用,俺想不出场景,你在pointcut上加个call试一下。
2 楼 stamen 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究竟应用场合有什么区别,我们怎么看到它们不同的效果?
1 楼 partech 2007-01-23  
this标示调用方,target标示被调用方.

相关推荐

    征服Spring AOP—— @AspectJ

    1. `@Aspect`:标记一个类为切面类,此类包含切点和通知。 2. `@Pointcut`:定义一个切点表达式,用于匹配特定的代码执行点,如方法调用、构造器调用等。 3. `@Before`:前置通知,方法在目标方法执行前被调用。 4. ...

    @AspectJ配置Spring AOP,demo

    在这个例子中,`LoggingAspect`类被标记为切面,`logBefore`和`logAfterReturning`是通知方法,分别在方法执行前和成功返回后执行。 **二、切点表达式** 切点表达式是@AspectJ中的核心,它定义了何时以及在哪些...

    Spring的AOP实例(XML+@AspectJ双版本解析+源码+类库)

    下面将分别针对XML配置和@AspectJ注解方式详细解释这两个版本的AOP实例。 ### XML配置版AOP 在Spring的XML配置中,AOP通过 `&lt;aop:config&gt;` 和 `&lt;aop:advisor&gt;` 等标签来定义切面和通知。首先,我们需要定义一个切...

    Spring @AspectJ 实现AOP 入门例子

    在Java世界中,Spring框架是企业级应用开发的首选,它提供了一系列强大的功能,包括依赖注入、面向切面编程(AOP)等。本篇文章将深入探讨如何利用Spring的@...希望这个入门例子能帮助你理解和应用Spring的AOP功能。

    Spring AOP @AspectJ 入门实例

    这个实例中的"Spring_aop_aspectj"可能包含了示例代码,你可以下载并运行,以加深理解。同时,阅读博客文章(链接已给出)会提供更详细的解释和示例,帮助你更好地掌握Spring AOP和@AspectJ的实际应用。

    Spring AOP 概念理解及@AspectJ支持

    **Spring AOP 概念理解** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的一个重要组成部分,它允许我们通过...理解和熟练运用Spring AOP及其@AspectJ注解是每个Spring开发者必备的技能之一。

    Spring4 In Action-4.2-@AspectJ-切面

    Spring4 In Action-4.2-@AspectJ-切面,Spring4 In Action-4.2-@AspectJ-切面。Spring4 In Action-4.2-@AspectJ-切面

    spring AOP 实例(@AspectJ)

    一个基于@AspectJ的spring2.0 AOP应用实例,很小很简单,没有任何额外信息,最适合AOP入门学习。使用log4j打印信息。把项目直接import进myeclipse就可以使用啦......

    讨论AspectJ之target、this、within关键字差异性

    本篇文章将深入探讨AspectJ中的三个重要关键字:target、this和within,以及它们在定义切面范围时的区别。 首先,我们来了解`target`关键字。在AspectJ中,`target`关键字用于指定通知(advice)应该应用到哪些类型...

    aspectj用的的jar包

    AspectJ包含两个主要的jar包:aspectjweaver.jar和aspectjrt.jar。 1. aspectjweaver.jar:这是AspectJ的核心库,包含了运行时所需的编织器(weaver)。编织器是AspectJ实现AOP的关键组件,它可以在编译时或运行时...

    spring对AOP的支持(使用AspectJ进行AOP演示)

    接下来,我们创建一个切面类,使用 AspectJ 注解来定义切点(Pointcut)和通知(Advice)。例如: ```java @Aspect public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public ...

    aspectj和aspectjweaver

    AspectJ和AspectJ Weaver是两个在Java开发中用于实现面向切面编程(AOP)的重要工具。面向切面编程是一种编程范式,它旨在提高代码的模块化,通过将关注点分离,使得业务逻辑与系统服务(如日志、事务管理等)能够更好...

    AspectJ的JAR包

    2. 定义切面:创建一个Java类作为切面,通过使用AspectJ的注解(如`@Aspect`、`@Before`、`@After`、`@Around`、`@Pointcut`等)来声明切点和通知。 3. 配置切点:`@Pointcut`注解用于定义一个或多个切点表达式,...

    aspectj.weaver 和 aspectj.tools 类包

    aspectj.weaver 和 aspectj.tools 类包 Spring 4.X 使用@AspectJ和Schema 报错,添加aspectj.weaver 和 aspectj.tools 类包的依赖。

    aspectJ

    通过@Aspect注解,我们可以创建一个切面类,然后使用其他注解如@Pointcut、@Before、@After等来定义和关联切点和通知。 5. **类型匹配(Type Matching)**:AspectJ不仅支持基于方法签名的切点匹配,还支持更复杂的...

Global site tag (gtag.js) - Google Analytics