来自Spring 文档:
代理实现 AccountService 接口的任何连接点(仅在 Spring AOP 中执行方法):
this(com.xyz.service.AccountService)
目标对象实现 AccountService 接口的任何连接点(仅在 Spring AOP 中执行方法):
target(com.xyz.service.AccountService)
我不明白“目标对象”和表达的target(...)
意思。
有什么target
不同this
?
来自Spring 文档:
代理实现 AccountService 接口的任何连接点(仅在 Spring AOP 中执行方法):
this(com.xyz.service.AccountService)
目标对象实现 AccountService 接口的任何连接点(仅在 Spring AOP 中执行方法):
target(com.xyz.service.AccountService)
我不明白“目标对象”和表达的target(...)
意思。
有什么target
不同this
?
this(AType)
表示所有this instanceof AType
为真的连接点。因此,这意味着在您的情况下,一旦调用到达 AccountService 的任何方法,this instanceof AccountService
都将为真。
target(AType)
表示 的所有连接点anObject instanceof AType
。如果您在对象上调用方法并且该对象是 AccountService 的实例,那么这将是一个有效的连接点。
总结一种不同的方式 -this(AType)
是从接收者的角度来看,并且target(AType)
是从呼叫者的角度来看。
我知道这是一篇旧帖子,但我只是在不使用 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)"
。请注意,我使用了 this,而不是target。
如果您改用target,则您正在尝试匹配原始 class a.b.c.D
,而不是引入的 interface X
。所以 Spring AOP 不会在a.b.c.D
.
总之:
this - 检查代理类型或引入类型。 target - 检查声明的类型。
来自官方文档:
Spring AOP 是一个基于代理的系统,它区分代理对象本身(绑定到'this')和代理背后的目标对象(绑定到'target')。
This topic is often a source of confusion when it comes to AOP programming. I found a very good excerpt explanation on the web which summaries the differences:
this limits matching to join points where the bean reference is an instance of the given type, while target limits matching to join points where the target object is an instance of the given type. The former works when Spring AOP creates a CGLIB-based proxy, and the latter is used when a JDK-based proxy is created.
Suppose that the target class implements an interface:
public class FooDao implements BarDao { ... }
In this case, Spring AOP will use the JDK-based proxy and you should use the target PCD because the proxied object will be an instance of Proxy class and implement the BarDao interface:
@Pointcut("target(com.baeldung.pointcutadvice.dao.BarDao)")
On the other hand if FooDao doesn't implement any interface or proxyTargetClass property is set to true then the proxied object will be a subclass of FooDao and the this PCD could be used:
@Pointcut("this(com.baeldung.pointcutadvice.dao.FooDao)")
You can find out more on the following link:
我试图为目标和这个切入点指示符提供外行代码。已经太晚了,但希望对某人有所帮助。
方面类
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