Search code examples
springaopspring-aop

AOP Pointcut expression for methods belonging to classes in various subpackages


Context: I am running a Spring service that deals with interaction with external partners and vendors. I'm implementing a monitoring aspect to keep track of the QPS as well as other performance metrics for each of these external APIs.

They are implemented in a way where there is a parent class with an abstract protected execute() method that is being implemented for each vendor. (i.e. each vendor has its own class).

The directory is organized as such:

com.org.biz.vendor.impl.{vendor}.{vendorServiceProviderClass}

i.e.

  • com/org/biz/service/vendor/impl/vendorA/VendorAServiceProvider
  • com/org/biz/service/vendor/impl/vendorB/VendorBServiceProvider

where each Provider class overrides the execute() method. They are all named with a -Provider suffix.

I have tried to apply the Pointcut as follows:

@Pointcut("execution(protected * com.org.biz.service.vendor.impl..*Provider.doExecute(..))")
    public void monitoringPointCut() {
    }

    @Around("monitoringPointCut()")
    public Object writeToMetrics(ProceedingJoinPoint pjp) throws Throwable {
        // compute metrics and write to logs
    }

I have also tried some other variants but I can't seem to get the method intercepted regardless of which vendor implementation I tried to trigger. I'm not sure if it's because it is an overriden method, or if it's because its protected.

Any help would be greatly appreciated


Solution

  • Try something like this (I invented a class and package name for the abstract base class):

    execution(* com.org.biz.service.base.AbstractProvider+.doExecute(..))
    

    The + means "include subclasses".

    You could also write it like this:

    within(com.org.biz.service.base.AbstractProvider+) && execution(* doExecute(..))
    

    Now the subclass names and their package names do not matter anymore, because you are focusing on inheritance rather than naming.