代理所在的任何连接点(仅在Spring AOP中执行的方法) 实现AccountService接口:
this(com.xyz.service.AccountService)
目标所在的任何连接点(仅在Spring AOP中执行的方法) object实现AccountService接口:
target(com.xyz.service.AccountService)
我不明白“目标对象”和表达式target(...)
是什么意思。
target
与this
的区别如何?
答案 0 :(得分:21)
this(AType)
表示this instanceof AType
为真的所有加入点。所以这意味着,在您的情况下,一旦调用达到AccountService this instanceof AccountService
的任何方法都将为真。
target(AType)
表示anObject instanceof AType
所有加入点。如果要在对象上调用方法,并且该对象是AccountService的实例,那么它将是一个有效的连接点。
总结一种不同的方式 - this(AType)
来自接收者的角度,target(AType)
来自呼叫者的角度。
答案 1 :(得分:10)
我知道这是一篇很老的帖子,但我在没有使用AspectJ时遇到了这个和目标之间的重要区别。
考虑以下介绍方面:
@Aspect
public class IntroductionsAspect {
@DeclareParents(value="a.b.c.D", defaultImpl=XImpl.class)
public static X x;
@After("execution(* a.b.c.D.*(..)) && this(traceable)")
public void x(Traceable traceable) {
traceable.increment();
}
}
简而言之,这方面做了两件事:
a.b.c.D
类实现X
接口。traceable.increment()
的每个方法之前添加对a.b.c.D
的调用。重要的部分是"execution(* a.b.c.D.*(..)) && this(traceable)"
。请注意,我使用此,而不是目标。
如果您使用目标,则尝试匹配原始类a.b.c.D
,而不是引入的接口X
。所以Spring AOP在a.b.c.D
中找不到任何连接点。
总结:
此 - 检查代理类型或引入的类型。 目标 - 检查声明的类型。
答案 2 :(得分:6)
来自官方文件:
Spring AOP是一个基于代理的系统,它区分代理对象本身(绑定到'这个')和代理背后的目标对象(绑定到' target')。
答案 3 :(得分:0)
我试图给出目标和这个切入点指示符的外行代码。已经为时已晚,但希望对某人有所帮助。
方面的课程
package com.opensource.kms;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class SecurityService {
@Pointcut("target(com.opensource.kms.FooDao)")
public void myPointCut1() {}
@Pointcut("this(com.opensource.kms.SooDao)")
public void myPointCut2() {}
@Before("myPointCut1()")
public void beforeMethodTarget() {
System.out.println("beforeMethodTarget myPointCut1");
}
@Before("myPointCut2()")
public void beforeMethodThis() {
System.out.println("beforeMethodThis myPointCut2");
}
}
FooDao类:JDK动态代理
package com.opensource.kms;
import org.springframework.stereotype.Component;
interface BarDao {
String m();
}
@Component
public class FooDao implements BarDao {
public String m() {
System.out.println("implementation of m");
return "This is return value";
}
}
SooDao类:CGLIB代理
package com.opensource.kms;
import org.springframework.stereotype.Component;
@Component
public class SooDao {
public String m() {
System.out.println("implementation of m : SooDao");
return "This is return value";
}
}
主应用
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
SooDao ob1 = ctx.getBean("sooDao", SooDao.class);
System.out.println("Data using this ->"+ob1.m());
System.out.println("********************");
BarDao ob2 = ctx.getBean("fooDao", BarDao.class);
System.out.println("Data using target -> "+ob2.m());
输出
beforeMethodThis myPointCut2
implementation of m : SooDao
Data using this ->This is return value
********************
beforeMethodTarget myPointCut1
implementation of m
Data using target -> This is return value
答案 4 :(得分:0)
当涉及到 AOP 编程时,这个话题常常是一个混乱的来源。我在网上找到了一个很好的摘录解释,总结了差异:
<块引用>this 限制匹配连接点,其中 bean 引用是给定类型的实例,而 target 限制匹配连接 目标对象是给定类型的实例的点。这 前者在 Spring AOP 创建基于 CGLIB 的代理时起作用,而 后者在创建基于 JDK 的代理时使用。
假设目标类实现了一个接口:
public class FooDao implements BarDao {
...
}
在这种情况下,Spring AOP 将使用基于 JDK 的代理,您应该 使用目标 PCD,因为代理对象将是 代理类并实现BarDao接口:
@Pointcut("target(com.baeldung.pointcutadvice.dao.BarDao)")
另一方面,如果 FooDao 没有实现任何接口或 proxyTargetClass 属性设置为 true 则代理对象将 是 FooDao 的子类,可以使用这个 PCD:
@Pointcut("this(com.baeldung.pointcutadvice.dao.FooDao)")
您可以通过以下链接了解更多信息: