谈谈自定义注解及相关开发实践

说道自定义注解,可能大家都不太陌生,实际开发过程中可能多多少少也会用到,今天这边就通过自定义注解结合反射,分享一些实际开发经验。

好吧,关于什么是自定义注解,以及元注解什么什么的我这边就不一一介绍了,大家自行百度,内容也都比较简单固定,随便一篇博客都可以讲的很清楚,我这边分享更主要的是关于一些实际开发过程中,关于自定义注解的使用。

下面来看一些这样一个业务场景:
在这里插入图片描述
这是一个简单得业务模型,相信很多同学在实际业务开发中也都是随处可见的,核心服务通过网关调用第三方服务,这个模型很简单。下面来看下加上一些实际业务在里面:
在这里插入图片描述
看上面业务场景,如果有很多个业务在里面需要经过网关(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();

好了以上便是我日常工作中的一个实际组件开发案例,希望可以对大家有所帮助,有不足之处可以评论指正!

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