Search code examples
aopaspectjspring-aop

AOP - @Pointcut syntax: how define the method with a superclass argument/parameter


I am working with Spring Framework and AspectJ version 1.8.9

I have many Service classes, lets consider for example

  • CustomerServiceImpl
  • InvoiceServiceImpl
  • CarServiceImpl

The point is, each one has a saveOne method. Therefore

  • saveOne(Customer customer)
  • saveOne(Invoice invoice)
  • saveOne(Car car)

If I use the following:

@Pointcut(value="execution(* com.manuel.jordan.service.impl.*ServiceImpl.saveOne(Car, ..)) && args(entity) && target(object)")
public void saveOnePointcut(Car entity, Object object){}

@Before(value="ServicePointcut.saveOnePointcut(entity, object)")
public void beforeAdviceSaveOne(Car entity, Object object){

It works. Until here for a better understanding:

  • The first parameter represents the Entity (Car in this case) to persist
  • The second parameter represents the Object or target (XServiceImpl) has been 'intercepted'

Note: I need the first parameter for audit and logging purposes. Therefore it is mandatory.

To avoid do verbose and create more for each entity, I want use a 'superclass' type. I've tried with

@Pointcut(value="execution(* com.manuel.jordan.service.impl.*ServiceImpl.saveOne(Object, ..)) && args(entity) && target(object)")
public void saveOnePointcut(Object entity, Object object){}

@Before(value="ServicePointcut.saveOnePointcut(entity, object)")
public void beforeAdviceSaveOne(Object entity, Object object){

Observe the first parameter now is an Object And it does not work.

If is possible accomplish this requirement, what is the correct syntax?

I've read Clarification around Spring-AOP pointcuts and inheritance but it is about only for methods without parameter(s)


Solution

  • You can try to use Object+ instead of just Object. + means all classes that extend target class. So your aspect code will look like this:

    @Pointcut(value="execution(* com.manuel.jordan.service.impl.*ServiceImpl.saveOne(Object+, ..)) && args(entity) && target(object)")
    public void saveOnePointcut(Object entity, Object object){}
    
    @Before(value="ServicePointcut.saveOnePointcut(entity, object)")
    public void beforeAdviceSaveOne(Object entity, Object object){
    

    I tried this with my code samples and it's work fine for all type of arguments.