Spring AOP target() vs this()

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:

Introduction to Pointcut Expressions in Spring


From official documentation:

Spring AOP is a proxy-based system and differentiates between the proxy object itself (bound to 'this') and the target object behind the proxy (bound to 'target').

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-pointcuts-designators


I know this is an old post but I just came across an important difference between this and target while not using AspectJ.

Consider the following introduction aspect:

@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();
    }

}

Simply put, this aspect is doing two things:

  1. Making the a.b.c.D class implement the X interface.
  2. Adding a call to traceable.increment() to be executed before each method of a.b.c.D.

The important part is "execution(* a.b.c.D.*(..)) && this(traceable)". Notice that I used this, not target.

If you use target instead, you are trying to match the original class a.b.c.D, not the introduced interface X. So Spring AOP will not find any join point in a.b.c.D.

In summary:

this - Checks the proxy type, or introduced type. target - Checks the declared type.


this(AType) means all join points where this instanceof AType is true. So this means that in your case once the call reaches any method of AccountService this instanceof AccountService will be true.

target(AType) means all join points where anObject instanceof AType . If you are calling a method on an object and that object is an instanceof AccountService, that will be a valid joinpoint.

To summarize a different way - this(AType) is from a receivers perspective, and target(AType) is from a callers perspective.