反射+注解

      这篇文章主要是记录注解和反射的使用。网上的相关文档和参考资料有很多,在参考部分以及结合我们公司原本的注解的使用,我觉得可以记录一下,主要用于备忘。

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的,然后再做后续的逻辑处理的)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个 Java 示例代码,使用注解+反射+枚举实现字典方法: ```java import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; @Retention(RetentionPolicy.RUNTIME) @interface DictionaryEntry { String key(); String value(); } enum Dictionary { FRUIT, COLOR, ANIMAL; } public class Main { private static Map<String, Map<String, String>> dictionaryMap = new HashMap<>(); public static void main(String[] args) { initDictionary(); String fruitName = "apple"; String fruitColor = getDictionaryValue(Dictionary.FRUIT, fruitName); System.out.println(fruitName + " is " + fruitColor); String colorName = "red"; String colorHex = getDictionaryValue(Dictionary.COLOR, colorName); System.out.println(colorName + " is " + colorHex); String animalName = "dog"; String animalSound = getDictionaryValue(Dictionary.ANIMAL, animalName); System.out.println(animalName + " says " + animalSound); } private static void initDictionary() { // Fruit dictionary Map<String, String> fruitMap = new HashMap<>(); fruitMap.put("apple", "red"); fruitMap.put("banana", "yellow"); fruitMap.put("orange", "orange"); dictionaryMap.put(Dictionary.FRUIT.name(), fruitMap); // Color dictionary Map<String, String> colorMap = new HashMap<>(); colorMap.put("red", "#FF0000"); colorMap.put("green", "#00FF00"); colorMap.put("blue", "#0000FF"); dictionaryMap.put(Dictionary.COLOR.name(), colorMap); // Animal dictionary Map<String, String> animalMap = new HashMap<>(); animalMap.put("dog", "woof"); animalMap.put("cat", "meow"); animalMap.put("bird", "tweet"); dictionaryMap.put(Dictionary.ANIMAL.name(), animalMap); } private static String getDictionaryValue(Dictionary dict, String key) { Map<String, String> dictMap = dictionaryMap.get(dict.name()); for (Map.Entry<String, String> entry : dictMap.entrySet()) { if (entry.getKey().equals(key)) { return entry.getValue(); } } return null; } static { for (Dictionary dict : Dictionary.values()) { Map<String, String> dictMap = new HashMap<>(); Class<?> dictClass; try { dictClass = Class.forName(dict.name()); } catch (ClassNotFoundException ex) { continue; } for (Field field : dictClass.getDeclaredFields()) { if (field.isAnnotationPresent(DictionaryEntry.class)) { DictionaryEntry entry = field.getAnnotation(DictionaryEntry.class); dictMap.put(entry.key(), entry.value()); } } dictionaryMap.put(dict.name(), dictMap); } } static class Fruit { @DictionaryEntry(key = "apple", value = "red") public static String APPLE; @DictionaryEntry(key = "banana", value = "yellow") public static String BANANA; @DictionaryEntry(key = "orange", value = "orange") public static String ORANGE; } static class Color { @DictionaryEntry(key = "red", value = "#FF0000") public static String RED; @DictionaryEntry(key = "green", value = "#00FF00") public static String GREEN; @DictionaryEntry(key = "blue", value = "#0000FF") public static String BLUE; } static class Animal { @DictionaryEntry(key = "dog", value = "woof") public static String DOG; @DictionaryEntry(key = "cat", value = "meow") public static String CAT; @DictionaryEntry(key = "bird", value = "tweet") public static String BIRD; } } ``` 这个例子中,我们创建了一个枚举类型 `Dictionary`,表示三个不同的字典:`FRUIT`、`COLOR`、`ANIMAL`。我们使用注解 `@DictionaryEntry` 来标记每个字典的条目,然后使用反射初始化字典。 在 `initDictionary` 方法中,我们创建了一个 `dictionaryMap`,包含了每个字典的名称和条目。我们使用反射枚举每个字典的条目,并将它们添到 `dictionaryMap` 中。 在 `getDictionaryValue` 方法中,我们通过枚举类型 `Dictionary` 和键值 `key` 获取字典中的值。我们首先从 `dictionaryMap` 中获取对应的字典,然后遍历字典中的条目,查找与给定键值匹配的条目并返回它的值。 注意,这个例子只是一个简单的演示,实际应用中可能需要更复杂的字典结构和查询方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值