Baeldung has this section:
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 we should use the target PCD because the proxied object will be an instance of the 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 the proxyTargetClass property is set to true, then the proxied object will be a subclass of FooDao and we can use the this PCD:
@Pointcut("this(com.baeldung.pointcutadvice.dao.FooDao)")
I'm still confuse why this just works with CGLIB proxy and target just works with JDK proxy. Could you help to tell me the different between them?
Actually, the explanation in the tutorial does not make much sense:
this(MyInterface)
and target(MyInterface)
work for JDK proxies, if the bean is declared as a MyInterface
type.this(MyClass)
and target(MyClass)
work for CGLIB proxies, if the bean is declared as a MyClass
type. Just try, and you will see that I am right. In Spring AOP, there is not real difference between this()
and target()
, because due to its proxy-based nature, it implicitly only supports execution()
pointcuts from AspectJ.
In native AspectJ however, you also have other pointcut types such as call()
, and there you would see a difference: this()
would match the caller's type, while target()
would match the callee's type. Eg, if you intercept a method Aa()
calling Bb()
via pointcut call(Bb())
, this()
would return an A
instance, while target()
would return a B
instance. Do not worry, if this is difficult to understand for you, because for Spring AOP and execution pointcuts it really does not matter.
The only subtle difference I noticed in Spring AOP is, that for MyInterfaceImpl implements MyInterface
, pointcut target(MyInterfaceImpl)
would actually match, while this(MyInterfaceImpl)
would not. This is because for JDK proxies, the proxy actually extends java.lang.reflect.Proxy
, not MyInterfaceImpl
. The proxy only delegates to a MyInterfaceImpl
instance. I would have to write a lot in order to explain the semantics here, but I do not want to make the matter even more complicated.
Bottom line: For all intents and purposes, in normal use cases you can use either this()
or target()
for both JDK and CGLIB proxies. I recommend to stick with target()
, because it best matches the implicit execution()
semantics of Spring AOP.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.