AOP with custom annotation in Super class doesn

2019-07-25 23:18发布

问题:

custom annotation

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
}

custom annotation handler

@Aspect
public class TestAspectHandler {
    @Around("execution(@com.test.project.annotaion.CustomAnnotation * *(..)) && @annotation(customAnnotation)")
    public Object testAnnotation(ProceedingJoinPoint joinPoint, CustomAnnotation customAnnotation) throws Throwable {
        System.out.println("TEST");
        return result;
    }
}

super class

public class AbstractDAO {
     @CustomAnnotation
     protected int selectOne(Object params){
          // .... something
     }
}

sub class

public class SubDAO extends AbstractDAO {
    public int selectSub(Object params) {
         return selectOne(params);
    }
}

subclass SubDAO call SuperClass method selectOne but in TestAspectHandler.class doesn't call testAnnotation(...)

when i move @CustomAnnotation to subclass selectSub(..) method AspectHandler can get joinPoint

how to work with Custom annotation in super class protected method?


added

change TestAspectHandler.testAnnotation(...) method

@Around("execution(* *(..)) && @annotation(customAnnotation)")
public Object testAnnotation(ProceedingJoinPoint joinPoint, CustomAnnotation customAnnotation) throws Throwable {
            System.out.println("TEST");
            return result;
}

but still doesn't work

so i chnage my SubDAO like under code

public class SubDAO extends AbstractDAO {
    @Autowired
    private AbstractDAO abstractDAO;
    public int selectSub(Object params) {
         return abstractDAO.selectOne(params);
    }
}

this is not the perfect solution but it work


  • case 1 : call Super class method from subclass method doesn't work
  • case 2 : make Super class instance and call from instance work

回答1:

First of all, I hope that your DAO classes are actual Spring components, otherwise Spring AOP does not find them, only AspectJ could.

But at the core of it this is not a Spring or AspectJ problem. In Java, annotations on

  • interfaces,
  • other annotations or
  • methods

are never inherited by

  • implementing classes,
  • classes using annotated annotations or
  • overriding methods.

Annotation inheritance only works from classes onto subclasses, but only if the annotation type used in the superclass bears the meta annotation @Inherited, see JDK JavaDoc.

Because I have answered this question several times before, I have just documented the problem and also a workaround in Emulate annotation inheritance for interfaces and methods with AspectJ.


Update: Sorry, I just inspected your code more thoroughly. You are not overriding the superclass's annotated method (at least your code does not show that you override method selectOne), so what I described above does not apply here. Your aspect should work. But maybe you just have a typo in the fully qualified class name @com.test.project.annotaion.CustomAnnotation: The annotaion (note the typo!) package name should probably rather be annotation. And as I said in my first sentence: The DAOs must be Spring @Components.

And by the way: You can avoid that part of the pointcut altogether because you already bind the annotation to a parameter. Just use

@Around("execution(* *(..)) && @annotation(customAnnotation)")


回答2:

The way it works is that your spring bean proxy (every reference to a spring bean is actually a proxy which delegates to the bean instance) creates JDK Dynamoc proxy (for class which implements at least 1 interface or CGLib proxy) for your applied aspects. so when the selectSub method is invoked, it's already passed the spring bean delegation and the aspect cannot be applied. if you want to get it work you will have to annotate the sub method as well.