今天在自定義註解的時候,原計劃實現一個類似於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
通過這種方式,我們就可以實現組合註解功能了,這樣我們在自定義註解時,可以將很多具有公共屬性的註解進行提取,通過註解繼承的方式完成組合註解的實現了;
是不是很簡單~~~