註解 java.lang.annotation.Inherited 介紹

在Spring Boot中大量使用了@Inherited註解。咱們來了解一下這個註解的用法,註解的源碼:java

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註解,看下源碼中的紅色部分:this

@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 {

  // .....省略

}

那麼如今有一個咱們本身開發的類使用了這個註解,例如:spa

@SpringBootApplication
@Service
public class Person { }

而後有個類Employee繼承了Personcode

public class Employee extends Person{

}

那麼如今在判斷Employee類上有沒有@SpringBootApplication時,經過代碼驗證:blog

@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) 爲止。若是沒有超類具備該類型的註釋,則查詢將指示當前類沒有這樣的註釋。開發

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

相關文章
相關標籤/搜索