Skip to content
Home » this and target pointcut of Spring AOP

this and target pointcut of Spring AOP

1. Overview

In this article, we will talk about this and target pointcut designators of Spring AOP. We will also see some examples to understand it better. See Pointcut in Spring AOP (pointcuts, expressions, designators) to know more information on pointcuts.

this limits matching to join points (the method executions) where the bean reference (Spring AOP proxy) is an instance of the given type.

target limits matching to join points (the method executions) where the target object (application object being proxied) is an instance of the given type.

2. this and target designators

Let’s recall the Jdk dynamic proxy and CGLIB proxy mechanisms to get a grasp on these concepts. We will also see this and target pointcut examples for each of these.

2.1. JDK Dynamic proxy

The Spring AOP is proxy-based. Suppose the target class implements at least one interface, then Spring uses JDK dynamic proxy to create a proxy object. The proxy object extends the same interface and proxies all the interface methods. The calls to the overridden methods of the target class will go to the proxy object first. Then the proxy object will delegate to all the advice declared for the target class.

The below target class CountriesRepositoryImpl implements an interface. So Spring uses Jdk dynamic proxy. It creates a proxy object which also implements the same interface.

@Component
public class CountriesRepositoryImpl implements CountryRepository {
    @Override
    public List<String> getCountries() {
       return countries;
    }
}
package com.tedbob.aspects;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class CurrenciesRepositoryAspect {

	@Before("target(com.tedbob.bls.CountryRepository)")
	public void beforeTargetCountriesRepository() {
	    System.out.println("beforeCountriesRepository");
	}

    @After("this(com.tedbob.bls.CountryRepository)")
	public void afterCountriesRepository() {
	    System.out.println("afterCountriesRepository");
	}

}

Target designator matches the target object which is of type com.tedblob.interface.CountryRepository. Here, the beforeTargetCountriesRepository advice matches the target class CountriesRepositoryImpl.

This designator matches the proxy object which is of type com.tedblob.interface.CountryRepository. Since the proxy object of CountryRepositoryImpl also implements the same interface CountryRepository, this advice executes.

2.2. CGLIB proxy

To prevent the JDK dynamic proxy, you can use @EnableAspectJAutoProxy(proxyTargetClass=true) annotation in your class. Also, if your target class doesn’t implement any interface, then Spring uses CGLIB proxy and creates a proxy object that will be a subclass of your target class.

@Component
public class CountriesRepositoryImpl {
    public List<String> getCountries() {
       return countries;
    }
}

Here, this designator matches the proxy object of type CountriesRepositoryImpl. As the proxy object is a subclass of CountriesRepositoryImpl, this advice executes whenever any call happens to the CountriesRepositoryImpl.

@Before("this(com.tedblob.interface.CountriesRepositoryImpl)")
public void beforeThisCountriesRepository() {
    System.out.println("beforeThisCountriesRepository");
}

The below target designator won’t work in this scenario as the target object doesn’t implement any interface and is not an instance of any type. Due to which “Exception in thread “main” org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.tedbob.interface.CountryRepository’ available” error occurs.

@Before("target(com.tedblob.interface.CountryRepository)")
public void beforeTargetCountriesRepository() {
    System.out.println("beforeCountriesRepository");
}

Consider the below scenario where the target class has the annotation @EnableAspectJAutoProxy(proxyTargetClass=true) to use CGLIB proxy. It also implements an interface. The target designator works here because the target object is of type CountryRepository.


@Component
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class CountriesRepositoryImpl implements CountryRepository {
    
	public int getCountriesCount() {
        return 0;
    }
}

package com.tedbob.aspects;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class CurrenciesRepositoryAspect {

	@Before("target(com.tedbob.bls.CountryRepository)")
	public void beforeTargetCountriesRepository() {
	    System.out.println("beforeCountriesRepository");
	}

    @After("this(com.tedbob.bls.CountriesRepositoryImpl)")
	public void afterCountriesRepository() {
	    System.out.println("afterCountriesRepository");
	}

    @Around("this(com.tedbob.bls.CountryRepository)")
	public int aroundCountriesRepository(ProceedingJoinPoint joinPoint) throws Throwable {
	    System.out.println("aroundCountriesRepository");
    	return (int) joinPoint.proceed();
	}
}

1 thought on “this and target pointcut of Spring AOP”

  1. Pingback: What is the JoinPoint argument used for? - TedBlob

Leave a Reply

Your email address will not be published. Required fields are marked *