通常我们会通过实现一个接口来编写一个类,为了省事,我将注解直接标注在了接口的方法上,实验发现通过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