0

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

jun
  • 192
  • 15
  • 1
    Are you not making a simple problem complicated? Why do you not use a pointcut intercepting the method based on the superclass, intercepting all overriding classes? Would that not suit your needs better and be more reliable than focusing on naming rules? Based on your reply, I can suggest a solution. But I need your feedback first. – kriegaex May 02 '23 at 15:02
  • hi @kriegaex, thanks for your response. yes, i realized that intercepting the method from the superclass would be sufficient. previously i had the misconception that I had to be intercepting concrete methods. – jun May 02 '23 at 17:00

1 Answers1

1

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.

kriegaex
  • 63,017
  • 15
  • 111
  • 202