Search code examples
javaspringaopaspectjspring-aop

@Aspect class with an advice signature similar to pointcut expression


I was learning AOP and came across a scenario .

All of the classes are within package com.spring and Pointcut defines @AfterReturning type of Advice for any method in any class of package com.spring with any number of arguments.

spring.xml is well defined, in my classpath and the provided code is running

So my question is, shouldn't this advice of Aspects class run infinitely as it itself satisfies Pointcut definition?

Here's my Aspect Class

package com.spring;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class Aspects {

    @AfterReturning(pointcut = "execution(* com.spring.*.*(..))", returning= "res")
    public void logAfterExecutionAdvice(int res){
        System.out.print("Result in advice: "+res);
         System.out.print(" In After Advice ");
  }
}

My Adder Class

package com.spring;

public class Adder {
    private int a;
    private int b;
    public int add(int a,int b){
       return (a+b);
    }
    /**
     * @return the a
     */
    public int getA() {
        return a;
    }
    /**
     * @param a the a to set
     */
    public void setA(int a) {
        this.a = a;
    }
    /**
     * @return the b
     */
    public int getB() {
        return b;
    }
    /**
     * @param b the b to set
     */
    public void setB(int b) {
        this.b = b;
    }
}

And my Main Class

package com.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {
    ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");
    Adder adder=(Adder)ctx.getBean("adder");
    System.out.print("Result=" + adder.add(2,3));
    }

}

The OUTPUT which I get is Result in advice: 5 In After Advice Result=5


Solution

  • As per the Spring's AOP documentation here -

    In Spring AOP, it is not possible to have aspects themselves be the target of advice from other aspects. The @Aspect annotation on a class marks it as an aspect, and hence excludes it from auto-proxying.

    The classes marks as @Aspect are excluded from the auto-proxing and pointcuts.

    So, if you try something like this -

    package com.spring;
    
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    
    @Aspect
    public class Aspects {
        @After("execution(* com.spring.Aspects.*(..))")
        public void logAfterExecutionAdvice(){
            System.out.print("In After Advice ");
        }
    }
    

    The Spring will give an error something like -

    Error:(12, 0) ajc: advice defined in com.spring.Aspects has not been applied [Xlint:adviceDidNotMatch]