I have a Parent and a SubClass. Parent has a variable A, and subclass has a variable B. When I do getA on parent/subclass my calls are going to the around aspect. What I want is that the call should only go to around when I'm calling getA or any subclass method on the subclass. It should not go to around when I'm calling get A parent.
Aspect on subclass only
1k Views Asked by Ankur Gupta AtThere are 2 best solutions below

If you want to avoid explicitly naming all subclasses in the aspect or explicitly annotating all subclasses - which both creates maintenance effort and can be forgotten - you can check the Spring bean's runtime type at the beginning of the advice method and skip all special processing like logging, assigning default return values etc.
This is further complicated by the fact that both the base class Employee
and its subclasses are targeted by Spring AOP, i.e. they are Spring proxies and you have to unwrap them first before you can get the real target class's type. This is generally done via AopTestUtils.getTargetObject(mySpringComponent)
.
I simplified your aspect code a bit in order to focus on the main issue:
package com.journaldev.spring.aspect;
import com.journaldev.spring.model.Employee;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.test.util.AopTestUtils;
@Component
@Aspect
public class EmployeeAroundAspect {
@Around("execution(* get*(..)) && this(employee)")
public Object employeeAroundAdvice(ProceedingJoinPoint proceedingJoinPoint, Employee employee) throws Throwable {
// Skip logging for base class 'this'
if (AopTestUtils.getTargetObject(employee).getClass().equals(Employee.class))
return proceedingJoinPoint.proceed();
System.out.println(proceedingJoinPoint);
Object value = proceedingJoinPoint.proceed();
System.out.println(" Return value = " + value);
return value;
}
}
P.S.: If you just wish to log the result, an @AfterReturning
advice might be easier because you do not have to proceed or handle/throw exceptions. But this is out of scope of your question. FWIW, the advice then would look like this:
@AfterReturning(pointcut = "execution(* get*(..)) && this(employee)", returning = "returnValue")
public void employeeAfterReturningAdvice(JoinPoint joinPoint, Employee employee, Object returnValue) {
// Skip logging for base class 'this'
if (AopTestUtils.getTargetObject(employee).getClass().equals(Employee.class))
return;
System.out.println(joinPoint);
System.out.println(" Return value = " + returnValue);
}
With the pointcut definition like that, both methods getA will be cut in parent and child, that is what it is supposed to work. So if you want to cut only on the child getA, you need to give some other information of the cut definition.
Such as adding an annotation
then only annotate to the child,
and define the aspect as
Then only getA in Child class will be aspected