Search code examples
javaannotationsaopaspectjspring-aop

Annotation with AOP - works at method level while only the class is annotated


I'm trying to create a custom annotation for my project. Here it is -

DataSourcePicker (annotation):

   import java.lang.annotation.ElementType;
   import java.lang.annotation.Retention;
   import java.lang.annotation.RetentionPolicy;
   import java.lang.annotation.Target;

   @Target({ElementType.METHOD, ElementType.TYPE})
   @Retention(RetentionPolicy.RUNTIME)
       public @interface DataSourcePicker {

   }

I've implemented the DataSourcePicker annotation using AOP like this -

DataSourcePickerAspect:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DataSourcePickerAspect implements Ordered {

    private int order;

    @Value("10")
    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return order;
    }

    @Pointcut(value="execution(public * *(..))")
    public void anyPublicMethod() { }


    @Around("@annotation(dataSourcePicker)")
    public Object pickDataSource(ProceedingJoinPoint pjp, 
    DataSourcePicker dataSourcePicker) throws Throwable {
        //some code...
    }
}  

With having these above all set up when I try to annotate my service class like this -

(Good Approach):

   @Service
   @DataSourcePiceker
   public SomeServiceClass{     
       pubic void method1(){}
       pubic int method2(List<Integer> list){}
       pubic String method3(String a, String b){}
   }

The above code (SomeServiceClass) compiles fine. But neither of the methods are affected by the aspect(DataSourcePicker) I've written. But when I annotate my methods with DataSourcePicker it works as expected - all methods are intercepted by the DataSourcePickerAspect's @Around advice -

(Not So Good Approach, I guess):

   @Service
   @DataSourcePiceker
   public SomeServiceClass{
       @DataSourcePiceker     
       pubic void method1(){}

       @DataSourcePiceker
       pubic int method2(List<Integer> list){}

       @DataSourcePiceker
       pubic String method3(String a, String b){}
   }  

Can someone help me how to can I achieve the Good Approach? All I want to create an annotation and annotate a class with it while all methods of the class will be affected.

Thanks in advance


Solution

  • With @annotation(my.fancy.Annotation) you intercept annotated methods, while @within(my.fancy.Annotation) matches annotated classes, as documented in the Spring manual. Maybe you want to read it before using Spring AOP via trial & error.