在java中實現組合註解原理分析(註解繼承)

今天在自定義註解的時候,原計劃實現一個類似於Spring中的註解@Component的功能,如果稍有留意一下,會發現,在Spring中我們常見的註解,其實都繼承了@Component註解;如下圖所示:

如上圖所示,我們可以看到,我們常見的註解都繼承了註解@Component,而spring在啓動時進行類掃描的時候,也是掃描候選類上是否有攜帶@Component註解,有攜帶的話標記爲候選資源,否則的話不進行掃描;

 

但是,我們的原生java是不支持直接獲取當前類的所實現的註解的註解的;也就是說,我使用註解A標記了註解B,然後將註解B添加到類或者是方法上後,通過反射獲取到當前類,無法直接獲取到當前類是否有被註解A所標記;

 

那麼,在spring中是如何實現這種註解的集成@Component的呢;在這裏,使用代碼簡單實現一下註解的繼承;

 

首先,先創建一個Maven工程,然後我們自定義一個註解@Component

/**
 * 基礎註解,被此註解標記的類在spring掃描的包路徑下的話會被加入候選資源中
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyComponent {

    String name() default "";
}

創建好基礎註解後,我們再來創建一個註解@MyService,讓這個註解繼承基礎註解@Component,代碼如下:

/**
 * 類 名: MyService
 * 描 述: 自定義註解 -- 服務層 -- 定義在類、接口、枚舉上的
 * @author: jiaYao
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@MyComponent
public @interface MyService {

}

 

準備好這些工作後,再來創建一個測試類,讓這個測試類被註解@MySerice標記;

@MyService
public class UserService {
}

 

現在我們再寫一個main方法即可開始測試,代碼如下:

import javax.annotation.*;
import java.lang.annotation.*;

/**
 * 類 名: Main
 * 描 述: 測試組合註解
 * @author: jiaYao
 */
public class Main {

    public static void main(String[] args) {

        Class<UserService> classz = UserService.class;
        getAnnos(classz);
    }

    /**
     * interface java.lang.annotation.Documented 等 存在循環,導致內存溢出,所以需要排除java的源註解
     * @param classz
     */
    private static void getAnnos(Class<?> classz){
        Annotation[] annotations = classz.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() != Deprecated.class &&
                    annotation.annotationType() != SuppressWarnings.class &&
                    annotation.annotationType() != Override.class &&
                    annotation.annotationType() != PostConstruct.class &&
                    annotation.annotationType() != PreDestroy.class &&
                    annotation.annotationType() != Resource.class &&
                    annotation.annotationType() != Resources.class &&
                    annotation.annotationType() != Generated.class &&
                    annotation.annotationType() != Target.class &&
                    annotation.annotationType() != Retention.class &&
                    annotation.annotationType() != Documented.class &&
                    annotation.annotationType() != Inherited.class
                    ) {
                if (annotation.annotationType() == MyComponent.class){
                    System.out.println(" 存在註解 @MyComponent ");
                }else{
                    getAnnos(annotation.annotationType());
                }
            }
        }
    }
}

 

通過程序的輸出語句,我們在控制檯可以看到有輸出:

 存在註解 @MyComponent

 

通過這種方式,我們就可以實現組合註解功能了,這樣我們在自定義註解時,可以將很多具有公共屬性的註解進行提取,通過註解繼承的方式完成組合註解的實現了;

是不是很簡單~~~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章