Spring-AOP pointcut not working?

Below is my code snippet:

ServiceImpl.java

@Service
public class ServiceImpl implements Service {
  private Response worker(Audit send) throws ArgumentException {
    System.out.println("STEP_1");
    worker(send.getRequest(), send.getId());
  }

  private Response worker(Request request, String id) throws ArgumentException {
    System.out.println("STEP_2");
    try {
      //throwing some exception
    } catch (Exception e) {
      System.out.println("STEP_3");
    }
  }
}

      

Now I want that whenever NullPointerException

thrown out of a method worker(Request request, String id)

as shown above, I want to perform a specific task. For this, I wrote an Aspect class that is as follows:

MyAspect.java

@Aspect
@Component
public class MyAspect{
  @Pointcut("com.xyz.myapp.ServiceImpl.worker() && args(request,..)")
  private void someOperation(Request request) {}

  @Before("someOperation(request)")
  public void process(Request request) {
    System.out.println("SUCCESS");
  }

  @AfterThrowing("com.xyz.myapp.ServiceImpl.worker() && args(request,..)")
  public void doRecoveryActions() {
    System.out.println("EXCEPTION_SUCCESS");
  }
}

      

Current output:

STEP_1 
STEP_2
STEP_3

      

Desired output:

STEP_1 
STEP_2
STEP_3
SUCCESS
EXCEPTION_SUCCESS

      

As you can see, it MyAspect.java

does not start, so it does NOT print the values. What could be causing this?

Note:

  • I tried to make the worker as public class but it didn't work.

  • Also tried changing the name of the methods to fix the overloading issue which didn't work either.

  • Tried various pointcut expressions all in vain.

  • There are other aspect classes in my application that work absolutely fine.

+3


source to share


2 answers


You've made a typical Spring AOP beginner mistake: you assume it works for private methods, but as the documentation clearly states, it doesn't. Spring AOP is based on dynamic proxies and they only work for public methods when implementing interfaces through JDK proxies, and additionally for secure and batch methods when using CGLIB proxies.

You must make the method worker()

public if you want to intercept it from an aspect.

PS: Full-fledged AspectJ also works for private methods, but switching to a different AOP structure would be overkill.




Update: You also have other problems in your code:

  • The first method worker

    , even if you make it public, returns nothing. The last statement should be return worker(send.getRequest(), send.getId());

    , not only worker(send.getRequest(), send.getId());

    .
  • Your pointcut com.xyz.myapp.ServiceImpl.worker()

    will never match because it has an empty argument list, but your method has arguments. args()

    won't help you.
  • The syntax of your pointcut is also incorrect as it doesn't specify the return type for the method, not even *

    . Also, the method name itself is not enough, it must be wrapped in the actual pointcut type, for example execution()

    . That is, you want to write something like:
@Pointcut("execution(* com.xyz.myapp.ServiceImpl.worker(..)) && args(request, ..)")
private void someOperation(Request request) {}

      

+3


source


To intercept a method that throws an exception, you can use this code (only works if the methods are public):

 @AfterThrowing(pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",throwing="ex")
         public void doRecoveryActions(NullPointerException ex) {
          // ...
         }

      



Source: Spring AOP

+1


source







All Articles