zoukankan      html  css  js  c++  java
  • 注解 java.lang.annotation.Inherited 介绍

    在Spring Boot中大量使用了@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注解,例如SpringBoot中的 @SpringBootApplication注解,@SpringBootApplication注解类就定义了@Inherited注解,看下源码中的红色部分:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = {
            @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
            @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication {
    
      // .....省略
    
    }

    那么现在有一个我们自己开发的类使用了这个注解,例如:

    @SpringBootApplication
    @Service
    public class Person { }

    然后有个类Employee继承了Person

    public class Employee extends Person{
    
    }

    那么现在在判断Employee类上有没有@SpringBootApplication时,通过代码验证:

    @Test
        public void test1(){
            
            Class clazz = Employee.class ;
            if(clazz.isAnnotationPresent(SpringBootApplication.class)){
                System.out.println("true");     
            }
            
        }

    上面这个测试用例执行将输出true,也就是子类中能查找到@SpringBootApplication ,但同样,你用上述代码查找Employee类上是否有Spring的@Service注解时,会输出false,至此你应该明白@Inherited注解的用意了吧。

    经过这样的分析,我们再来读一下JDK的文档,就会比较容易理解了,否则会觉的有些绕,下面列出 @interface注解的中文文档:

    指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。

    注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。

  • 相关阅读:
    ubuntu在桌面创建快捷方式
    ubuntu下安装VMware
    常用docker命令
    转:如何在Ubuntu 14.04中安装最新版Eclipse
    docker初安装的血泪史
    关于ubuntu中文输入调用不出来的解决办法,具体如正文。
    测试linux下磁盘的读写速率
    pidstat 命令详解(转载)
    TCP/IP 协议栈4层结构及3次握手4次挥手
    nginx反向代理原理及配置详解
  • 原文地址:https://www.cnblogs.com/hzhuxin/p/7799899.html
Copyright © 2011-2022 走看看