这篇文章主要是记录注解和反射的使用。网上的相关文档和参考资料有很多,在参考部分以及结合我们公司原本的注解的使用,我觉得可以记录一下,主要用于备忘。
1.定义注解:注解的定义很简单,直接在ecplies中可以直接定义。他的结构类似于定义interface。只不过加上了@符号。
我们先看一个简单的定义:
这里可以简单的看出来,注解的定义需要声明@interface,以及使用java的@Retention和@Target。事实上,java还提供了@Document与@Inherited @Document表示 将注解包含到JavaDoc中 @Inherited允许子类继承父类的注解。
2.定义注解测试类,使用刚刚自定义的注解
这一步其实也很简单,就是在一个字段上,顶一个自定义的注解,其中注解内的两个元素clazz和defalutSelect都进行了默认的指向
3.反射解析注解的工具类实现
这个class的意思是我通过传入的class对象,拿到他每的每个字段,遍历这个集合,拿到字段的相应的注解(通过指定的注解去拿了),并且输出。
4.测试main类编写
测试结果:
至此,以上,就是全部的过程。下面我记录了一些遇到的坑,以及相关其他的涉及到的其他知识方面.
--------------------------------------------------------------------------
首先:这个原型代码是模仿这公司的DTO来进行做的。这里想解释一下DTO,以及在我们系统内的所起到的一些作用。
相关公司内部架构这边不以源码的形式进行展示,这边只是用文字描述一下。
DTO即 Data Transfer Object ,就是数据模型转化。我们公司开发框架模型是分布式,前后端分离开发。在以往开发的过程中,我们返回给前端的数据中会带有对象,而对象中可能还有对象,这样的话,前端接受到的数据会很庞大。其次,虽然我们实现了代码层面的分布式,但是由于各个业务模块会去引用基础模块的东西,所以我在后期分数据库表结构的时候会比较累。
在加了DTO之后,我们对数据进行了封装,通过DefaultSelect注解,在返回给前端数据的那一层时候,做了数据拦截和封装。一方面,通过配置的class找到相应的Bean,在去调用相应Bean的service的查询,另外一方面查询的字段,也不是整个的bean对象,而是我配置的字段。
当然,以上说的两个东西,不通过DTO我也能做到一定程度上的规避。1.在查询基础的Bean对象的时候,我可以配置默认的查询字段,但是这样做比较尴尬的是,我的默认查询就是直接定位到基础业务单据上了。假设,我对于A单据我要基础数据的ABC三个字段,B需要BCD的三个字段,那么在关联的业务单据上,我就需要ABCD四个字段,这样之后,关联查询的数据字段会越来越大,后期很不方便管理,而且浪费数据库资源。而使用DTO之后,我会将需要关联查询基础资料的字段,配置到业务单据上,也就是我A单据,要ABC三个字段,我就去查这三个字段,B单据就去查BCD三个字段,配置更加灵活。2.对于刚刚说的数据库的分离,我们在每个业务模块下,配置数据库的连接信息,每次查询的时候,需要判断数据库的连接信息,去查询。而DTO的做法是在我最后数据组装的时候,调用我想要的service的查询接口,两个方法感觉都可以。只是,都写不了复杂SQL(总感觉分布式,就是对SQL支持力度比较低,为了考虑分库,以及多个不同数据库类型)。
其次,我遇到了一个比较坑的问题,是在反射获取注解上的。
这是,我现在写的RefObject annotation = annotationField.getAnnotation(RefObject.class);
但是,在此之前,我是不准备直接获取固定的注解的,我是这么写的。
Annotation[] annotions = annotationField.getAnnotations();
然后遍历annotions,去instance of类型去做的,然后,在实际Debug过程中,这边变成了代理。
然后,这边refannotion 就变成了一个AnnotionInvocationHandler了,讲道理这里也是可以拿到我的class对象的,但是我直接去拿class对象的时候,就是一个代理了,输出的class也变了(其实我是想抓到classname的,然后再做后续的逻辑处理的)。