Java使用自定义注解+反射实现字典转换代码实例

 更新时间:2023年09月23日 08:28:42   作者:也曾眼眸有光  
这篇文章主要介绍了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使用自定义注解+反射实现字典转换代码实例的文章就介绍到这了,更多相关自定义注解+反射实现字典转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java Arrays.copyOf 功能示例代码

    Java Arrays.copyOf 功能示例代码

    Arrays.copyOf功能是实现数组的复制,返回复制后的数组,这篇文章主要介绍了Java Arrays.copyOf 功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • Java通过jedis连接redis的几种常用方法

    Java通过jedis连接redis的几种常用方法

    jedis封装了redis原有的操作命令,使用起来很简单,本文主要介绍了Java通过jedis连接redis的几种常用方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Java 存储模型和共享对象详解

    Java 存储模型和共享对象详解

    这篇文章主要介绍了Java 存储模型和共享对象详解的相关资料,对Java存储模型,可见性和安全发布的问题是起源于Java的存储结构及共享对象安全,需要的朋友可以参考下
    2017-03-03
  • 微服务中使用Maven BOM来管理你的版本依赖详解

    微服务中使用Maven BOM来管理你的版本依赖详解

    这篇文章主要介绍了微服务中使用Maven BOM来管理你的版本依赖,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • Java实现线程的四种方式解析

    Java实现线程的四种方式解析

    这篇文章主要介绍了Java实现线程的四种方式解析,线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程,一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序,需要的朋友可以参考下
    2023-10-10
  • java单例模式学习示例

    java单例模式学习示例

    java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种,下面提供了单例模式的示例
    2014-01-01
  • Java中如何将String转JSONObject

    Java中如何将String转JSONObject

    这篇文章主要介绍了Java中如何将String转JSONObject,String类型转JSONObject,下面有两种方式可以进行转换,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • Java从零实现超市会员管理系统

    Java从零实现超市会员管理系统

    这篇文章主要为大家详细介绍了Java实现超市会员管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-12-12
  • mybatis打印SQL,并显示参数的实例

    mybatis打印SQL,并显示参数的实例

    这篇文章主要介绍了mybatis打印SQL,并显示参数的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 如何将maven项目导出jar包(最简单方法)

    如何将maven项目导出jar包(最简单方法)

    大家都知道对于将maven项目导出jar包有好几种方式,本文给大家分享一种方式最容易且最方便,感兴趣的朋友跟随小编一起看看吧
    2023-11-11

最新评论