Actually, the explanation in the tutorial does not make much sense:
- Both
this(MyInterface)
and target(MyInterface)
work for JDK proxies, if the bean is declared as a MyInterface
type.
- Both
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. E.g., if you intercept a method A.a()
calling B.b()
via pointcut call(B.b())
, 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.
Edit: If you keep in mind that, in contrast to native AspectJ which involves no dynamic proxies, the semantics in Spring AOP are such that
this()
relates to the proxy object, while
target()
relates to the proxied object (proxy target),
it becomes clear why in this special case for JDK proxies target()
matches, but this()
does not.
Reference: Spring manual, section "Declaring a pointcut - examples":
this(com.xyz.service.AccountService)
: Any join point (method execution only in Spring AOP) where the proxy implements the AccountService
interface.
target(com.xyz.service.AccountService)
: Any join point (method execution only in Spring AOP) where the target object implements the AccountService
interface.
Only in this case, we are not asking for the interface class (which both the proxy and the target object implement), but for the implementation class itself.
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, and usually you are interested in information about the target rather than about the proxy..