标注在接口上的注解无效,无法使用aop拦截,即使声明了@Inherited

通常我们会通过实现一个接口来编写一个类,为了省事,我将注解直接标注在了接口的方法上,实验发现通过aop并没有拦截到该注解,即使在定义注解时使用了@Inherited元注解。
通过阅读@Inherited注解的源码,可以发现:

package java.lang.annotation;

/**
 * Indicates that an annotation type is automatically inherited.  If
 * an Inherited meta-annotation is present on an annotation type
 * declaration, and the user queries the annotation type on a class
 * declaration, and the class declaration has no annotation for this type,
 * then the class's superclass will automatically be queried for the
 * annotation type.  This process will be repeated until an annotation for this
 * type is found, or the top of the class hierarchy (Object)
 * is reached.  If no superclass has an annotation for this type, then
 * the query will indicate that the class in question has no such annotation.
 *
 * <p>Note that this meta-annotation type has no effect if the annotated
 * type is used to annotate anything other than a class.  Note also
 * that this meta-annotation only causes annotations to be inherited
 * from superclasses; annotations on implemented interfaces have no
 * effect.
 *
 * @author  Joshua Bloch
 * @since 1.5
 * @jls 9.6.3.3 @Inherited
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

标注了@Inherited元注解的自定义注解在接口中是不生效的,在类中生效也分情况:

  • 该注解的@Target必须是@Target(ElementType.TYPE),即该注解的使用范围必须是类级别。方法级别等是无效的。

举例说明,下面这种情况生效:
自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface NeedBye {
}

父类:

//注意该注解的使用位置
@NeedBye
abstract public class Waiter {
    public void greetTo(String name){};
    abstract public void serveTo(String name);
}

子类:

public class NaiveWaiter extends  Waiter {
    @Override
    public void greetTo(String clientName) {
        System.out.println("greeting to "+ clientName +"...");
    }
    @Override
    public void serveTo(String clientName) {
        System.out.println("serving to "+ clientName +"...");
    }
}

切面:

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AfterServingAspect {

    /*@After("execution(* serveTo(..))")
    public void afterServing(){
        System.out.println("Bye");
    }*/
//标注在类级别的注解,要使用@within,而不是@annotation
    @After("@within(com.smart.annotation.NeedBye)")
    public void afterServing(){
        System.out.println("Bye");
    }
}

运行结果:
这里写图片描述

具体运行参考:https://blog.csdn.net/my_wings/article/details/82018203

猜你喜欢

转载自blog.csdn.net/my_wings/article/details/82112318