自定义注解往往能够简化开发,当我们需要对某些类或者方法增加某些功能或者进行某些处理时,可以使用自定义注解做标注,减少代码侵入,实现低耦合。在自定义注解处理器中利用反射来完成想要的功能。
注解解释:
自定义注解例子:
需求:在导出功能中,对一些POJO的一些字段的导出原来是写死的,如果需要增加导出某个字段或者减少导出某个字段,都需要在业务代码中进行字段的添加和删除,另外导出后字段的列表顺序也得手动修改。
使用自定义注解后,利用注解的两个属性title(导出的列在excel表中的列名)、sort(导出的列在excel中的顺序),将注解标注在需要导出的字段上并声明列名和顺序即可。变更顺序或者增加列名只需要修改注解
和在字段上标注注解即可。
自定义注解:
/** * 用在需要导出的实体类的属性字段上 * 〈功能详细描述〉 * * @author 17090889 * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) * @see "ExportFieldProcessor" */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Export { /** * 导出的列的列名,必填 * * @return */ String title(); /** * 导出的列在excel中的顺序,必填 * * @return */ int sort(); }
自定义注解处理器:
/** * 注解@Export的处理器,返回需要导出的列的集合 * * @author 17090889 * @Export 〈功能详细描述〉 * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */ public class ExportFieldProcessor { /** * 解析指定的实体类的带有@Export注解的属性 * * @param clazz * @return */ public static Map resolveExportField(Class<?> clazz) { // 获取指定的class文件有哪些属性 Field[] fields = clazz.getDeclaredFields(); LinkedHashMap<String, String> fieldMap = new LinkedHashMap<>(); TreeMap<Integer, Map<String, String>> fieldTreeMap = new TreeMap<>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } }); // 遍历这些属性,判断哪些属性有@Export注解 for (Field field : fields) { if (field.isAnnotationPresent(Export.class)) { Export export = field.getAnnotation(Export.class); String fieldName = field.getName(); String title = export.title(); int sort = export.sort(); Map<String, String> hashMap = new HashMap<>(Constants.TWO); hashMap.put(fieldName, title); fieldTreeMap.put(sort, hashMap); } } // 遍历排序好的filed map // Set<Map.Entry<Integer, Map<String, String>>> entrySet = fieldTreeMap.entrySet(); // for (Map.Entry<Integer, Map<String, String>> entry : entrySet) { // Map<String, String> map = entry.getValue(); // fieldMap.putAll(map); // } fieldTreeMap.forEach((key, value) -> fieldMap.putAll(value)); return fieldMap; } }