Spring bean() pointcut doesn't work with OR statement

siemaeniu500 :

I am using Spring specific pointcut expression called bean(). For the following expression only the left part is being catched:

@AfterReturning("bean(FirstService).firstMethod(..) || bean(SecondService).secondMethod(..)")

if I do reverse, again the left part is being catched:

@AfterReturning("bean(SecondService).secondMethod(..) || bean(FirstService).firstMethod(..)")

If i write:

@AfterReturning("bean(SecondService).secondMethod(..)")

and @AfterReturning("bean(FirstService).firstMethod(..)") in two methods

then both works. What's wrong with the first OR statement ?

R.G :

The reason for this point cut expression to not work as expected is because it is incorrect. The Spring framework is not throwing any exception for this is another reason that leads to confusion.

As per the Spring Reference Documentation Section 5.4.3. Declaring a Pointcut the correct way to declare a bean() pointcut designator is as follows

bean(idOrNameOfBean)

The idOrNameOfBean token can be the name of any Spring bean. .

An aspect like the following code is the correct way to define the aspect and this will intercept all the method calls for both beans .

@Component
@Aspect
public class BeanAdviceAspect {

    @AfterReturning("bean(firstService) || bean(secondService)")
    public void logMethodCall(JoinPoint jp) {
        System.out.println(jp.getSignature());
    }
}

A point cut expression bean(firstService).firstMethod() is incorrect and the framework seems to discard anything after the bean(firstService) and that is the reason your testcases behaves differently when the declaration is reversed.

To confirm this behaviour , the following aspect

@Component
@Aspect
public class BeanAdviceAspect {

    @AfterReturning("bean(firstService).firstMethod() || bean(secondService)")
    public void logMethodCall(JoinPoint jp) {
        System.out.println(jp.getSignature());
    }
}

would also advice a method firstService.thirdMethod() for the reasons explained above.

Another way to declare bean pointcut designator is as follows . This matches the method execution in any Spring beans names that matches the wildcard expression.

@AfterReturning("bean(*Service)")
public void logMethodCall(JoinPoint jp) {
    System.out.println(jp.getSignature());
}

Hope this helps

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=292951&siteId=1