談談自定義註解及相關開發實踐

說道自定義註解,可能大家都不太陌生,實際開發過程中可能多多少少也會用到,今天這邊就通過自定義註解結合反射,分享一些實際開發經驗。

好吧,關於什麼是自定義註解,以及元註解什麼什麼的我這邊就不一一介紹了,大家自行百度,內容也都比較簡單固定,隨便一篇博客都可以講的很清楚,我這邊分享更主要的是關於一些實際開發過程中,關於自定義註解的使用。

下面來看一些這樣一個業務場景:
在這裏插入圖片描述
這是一個簡單得業務模型,相信很多同學在實際業務開發中也都是隨處可見的,核心服務通過網關調用第三方服務,這個模型很簡單。下面來看下加上一些實際業務在裏面:
在這裏插入圖片描述
看上面業務場景,如果有很多個業務在裏面需要經過網關(A,B,C。。。),我們以最簡單啊httpclient來說,是不是需要有很多的組件去接受我們的請求然後處理,這樣可以是可以,然後就是沒新接入一個業務,就需要新增一個組件或service去做入參轉換,調用,解析參數等等來處理,這樣對於實際開發,是不是很不方便,後期的開發維護成本也很高。那麼是不是可以做如下業務模型轉換;
在這裏插入圖片描述
如上圖,我們的網關服務就就漸漸演變成了如上模型,核心爲doDispatcher,爲公共組件,作爲真正的業務開發人員,只需要關係三個問題就好了:核心配置(就是業務對應的具體調用地址,不是我們關注點,不做贅述),調用入參的構造器,出參的解析器,這樣就可以大大簡化後續開發維護流程。

那麼問題來了:我們怎麼做到對應的業務能找到對應的參數構造器和參數解析器呢?

那麼我告訴你,使用自定義註解就可以很容易做到:下面我根據上述模型做了一個簡單的demo,給大家演示下如何使用自定義註解做代碼的調用路由(可以少寫一萬個if-else了)。
demo如下:
在這裏插入圖片描述
模擬上述業務模型,定義相關組件如下:
DispatcherService: 核心組件,做業務調用
ResultParse:返回參數解析組件
ParamContruct:入參構造組件
Request:同意調用入參
HandleConfig:自定義註解

(1)HandleConfig 設置爲運行時作用及作用域爲類上,定義兩個參數,爲我們的參數構造的Class以及出參解析Class,並做一個類型約束

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface HandleConfig {

    Class<? extends ParamContruct> contruct();

    Class<? extends ResultParse> parse();
}

(2)Request 這裏我們看一下A的實現,就是在入參處加上我們的自定義註解,告訴DispatcherService組件,我們這次請求需要的參數構造類和出參解析類是什麼

@EqualsAndHashCode(callSuper = true)
@Data
@HandleConfig(contruct = AParamContruct.class,parse = AResultParse.class)
public class ARequest extends Request {

    private static final long serialVersionUID = -5166944731599374964L;

    private String a;


}

(3)ParamContruct 和 ResultParse 不做解釋,分別打印一句話,做標記

public class AParamContruct implements ParamContruct{

   public void contruct() {
      System.out.println("執行了====A===的構造...");
   }
}

public class AResultParse implements ResultParse{

    public void parse() {
        System.out.println("執行了====A===的解析...");
    }
}

(4)DispatcherService 核心組件,這裏一個入參的泛型約束,在這裏我們就可以拿到我們的自定義註解,以及註解上的參數,再通過java的反射構建相應的參數對象做路由調用。

public class DispatcherService<T extends Request> {

    public void dispatcher(T request) throws IllegalAccessException, InstantiationException {
        HandleConfig handleConfig = request.getClass().getAnnotation(HandleConfig.class);
        ParamContruct paramContruct = handleConfig.contruct().newInstance();
        ResultParse resultParse = handleConfig.parse().newInstance();

        paramContruct.contruct();
        resultParse.parse();
    }
}

在這裏插入圖片描述
如上,我傳不同的參數,分別執行道路對應的參數構造類和參數解析類裏面去了,說明以及實現了我們上述的模型調用。

補充:對於DispatcherService 我們使用了反射來獲取入參的註解信息,幾個常見的反射方法如下:

//獲取類的指定註解信息
HandleConfig handleConfig = request.getClass().getAnnotation(HandleConfig.class);
request.getClass().getDeclaredAnnotation(HandleConfig.class);
//獲取類的所有註解信息
Annotation[] annotations =request.getClass().getAnnotations();
request.getClass().getDeclaredAnnotations();

好了以上便是我日常工作中的一個實際組件開發案例,希望可以對大家有所幫助,有不足之處可以評論指正!

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