Java使用自定义注解+反射实现字典转换代码实例
作者:也曾眼眸有光
这篇文章主要介绍了Java使用自定义注解+反射实现字典转换代码实例,注解是一种能被添加到java代码中的元数据,类、方法、变量、参数和包都可以用注解来修饰,注解对于它所修饰的代码并没有直接的影响,需要的朋友可以参考下
一、自定义注解类
import java.lang.annotation.*; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Dict { /** * 字典编码 */ String dictName(); /** * 实体类内对应的中文字段名,默认为“当前字段+Text” * <p> * 例如当前字段为“type”,则对应中文字段默认为“typeText” */ String dictField() default ""; }
二、AOP切面类
也可不使用切面,定义工具类进行处理
import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Slf4j @Aspect @Component public class DictAspect { @Pointcut("execution(* cn.stylefeng.guns.sys.modular.mapper.*.query*(..))") //指定mapper下所有查询方法 public void doPointcut() { } @AfterReturning(pointcut = "doPointcut()", returning = "result") public void doAfterReturning(JoinPoint pjp, Object result) { try { DictUtils.convertDict(result); } catch (Exception e) { log.error("查询结果字典转换失败", e); } } }
三、字典转换工具类
package cn.hsa.powersi.hygeia.pcloud.DictConverUtils; import cn.hsa.powersi.hygeia.pcloud.api.basic.iteminfo.Dict; import cn.hsa.powersi.hygeia.pcloud.api.sys.dto.SysCodeTableDetailDTO; import cn.hsa.powersi.hygeia.pcloud.basic.itemOwnType.dao.PhcItemTypeDAO; import cn.hsa.powersi.hygeia.pcloud.basic.itemOwnType.entity.PhcItemTypeDO; import cn.hsa.powersi.hygeia.pcloud.basic.storeseat.dao.PhcStoreSeatDAO; import cn.hsa.powersi.hygeia.pcloud.basic.storeseat.entity.PhcStoreSeatDO; import cn.hsa.powersi.hygeia.pcloud.com.base.dto.SelectDTO; import cn.hsa.powersi.hygeia.pcloud.comm.bo.BasDictBO; import cn.hsa.powersi.hygeia.pcloud.sys.bo.SysCodeTableDetailBO; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.Data; import lombok.SneakyThrows; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.FieldUtils; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * @ClassName DictUtils * @Description 转码工具类 需要在DTO中使用注解进行转码 * @Author 陈锐 * @Date 2023/8/21 10:32 * @Version 1.0 */ @Component public class DictUtils { private static SysCodeTableDetailBO sysCodeTableDetailBO; @Resource public void setSysCodeTableDetailBO(SysCodeTableDetailBO sysCodeTableDetailBO) { DictUtils.sysCodeTableDetailBO = sysCodeTableDetailBO; } private static final String DICT_FIELD_SUFFIX = "Name"; public static void convertDict(Object target) { if (target instanceof List) { List<?> objectList = ((List<?>) target); if (CollectionUtils.isNotEmpty(objectList)) { List<DictDefinition> dictDefinitions = getMetadata(objectList.get(0)); if (CollectionUtils.isEmpty(dictDefinitions)) return; Map<String, Map<String, String>> dictMapMap = getCodeTable(); objectList.forEach(t -> doConvertDict(t, dictDefinitions, dictMapMap)); } } else { List<DictDefinition> dictDefinitions = getMetadata(target); if (CollectionUtils.isEmpty(dictDefinitions)) return; Map<String, Map<String, String>> dictMapMap = getCodeTable(); doConvertDict(target, dictDefinitions, dictMapMap); } } /** * 仅获取一次Dict元数据,降低多次反射造成的性能消耗 * @param target 目标实体类 * @return Dict元数据 */ private static List<DictDefinition> getMetadata(Object target) { List<DictDefinition> dictDefinitions = new ArrayList<>(); if (ClassUtils.isPrimitiveOrWrapper(target.getClass()) || target instanceof Map || target instanceof String) { return dictDefinitions; } List<Field> fields = FieldUtils.getAllFieldsList(target.getClass()); for (Field field : fields) { Dict dict = AnnotationUtils.getAnnotation(field, Dict.class); if (dict != null) { DictDefinition dictDefinition = new DictDefinition(); dictDefinition.setDict(dict); dictDefinition.setField(field); dictDefinitions.add(dictDefinition); } } return dictDefinitions; } @SneakyThrows private static void doConvertDict(Object target, List<DictDefinition> dictDefinitions, Map<String, Map<String, String>> dictMapMap) { for (DictDefinition dictDefinition : dictDefinitions) { Dict dict = dictDefinition.getDict(); Field field = dictDefinition.getField(); Map<String, String> dictMap = dictMapMap.get(dict.dictName()); String dictCode = String.valueOf(FieldUtils.readField(target, field.getName(), true)); String dictField = StringUtils.isEmpty(dict.dictField()) ? field.getName() + DICT_FIELD_SUFFIX : dict.dictField(); FieldUtils.writeField(target, dictField, dictMap.get(dictCode), true); } } @Data public static class DictDefinition { private Dict dict; private Field field; } //获取码表 public static Map<String, Map<String, String>> getCodeTable(List<String> shopIdList){ ArrayList<String> codeTypeList = new ArrayList<>(); return codeTypeMap; } }
四、VO中使用注解确定需要字典转换的字段
@Data @AllArgsConstructor @NoArgsConstructor @Builder public class TestVo { private Integer id; private String name; private String idCard; /** * 性别(0、未知的性别 1、男性 2、女性) */ @Dict(dictName = "sex") private String sex; //字典翻译后的中文会赋值到该字段上面 private String sexName; }
到此这篇关于Java使用自定义注解+反射实现字典转换代码实例的文章就介绍到这了,更多相关自定义注解+反射实现字典转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!