注解 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) 為止。如果沒有超類具有該類型的注釋,則查詢將指示當前類沒有這樣的注釋。

注意,如果使用注釋類型注釋類以外的任何事物,此元注釋類型都是無效的。還要注意,此元注釋僅促成從超類繼承注釋;對已實現接口的注釋無效。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM