java注解方式处理实体类中的字典项

该文章介绍了一种使用Java自定义注解和AOP切面处理的方法,用于在运行时进行字典转换。通过定义`DictParam`和`DictHelper`注解,可以在字段级别指定数据字典类型和映射关系。在AOP切面`DictHelperAspect`中,文章展示了如何遍历对象属性,利用反射获取和设置字段值,从而实现字典值到业务对象的转换。同时,文章提供了一个初始化字典配置的`DictConfig`组件,从数据库加载字典数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.首先编写自定义注解

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictParam {
    /**
     * 映射目标属性,为空默认直接映射到field,替换掉原来的field
     *
     * @return
     */
    String targetField() default "";

    /**
     * 映射来源属性
     *
     * @return
     */
    String field();

    /**
     * 数据字典类型
     *
     * @return
     */
    String dictType();
}

2.自定义方法注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictHelper {
    /**
     * 字典转换参数配置
     */
    DictParam[] value();
}

3.使用aop的方式处理不同返回值的实体.此处写死了两种方法返回值,如果其他的更好的方式,欢迎大佬留言告诉我.谢谢

@Slf4j
@Aspect
@Component
public class DictHelperAspect {

    public static final String PAGE_INFO = "PageInfo";

    public static final String GET = "get";

    public static final String SET = "set";

    @Pointcut("@annotation(com.citycloud.bigdata.biz.clearance.common.dict.DictHelper)")
    private void dictHelper() {
    }

    @Around("dictHelper()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        try {
            // 执行方法得到结果
            Object result = joinPoint.proceed();

            //检查允许的字典项
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            if (method.isAnnotationPresent(DictHelper.class)) {
                DictHelper dictHelper = method.getAnnotation(DictHelper.class);
                DictParam[] values = dictHelper.value();
                if (values == null || values.length == 0) {
                    return result;
                }

                // 字典转换开始(使用反射)
                for (DictParam value : values) {
                    Class<?> clazz = result.getClass();
                    if (clazz.getName().contains(PAGE_INFO)) {
                        PageInfo<T> pageInfo = (PageInfo) result;
                        List<T> list = pageInfo.getList();
                        for (Object t : list) {
                            Class<?> voClass = t.getClass();
                            // 反射调用get方法获取字段值
                            Method sourceMethod = voClass.getMethod(GET + firstToUppercase(value.field()));
                            Object fieldValue = sourceMethod.invoke(t);
                            if (Objects.isNull(fieldValue)) {
                                continue;
                            }
                            Map<String, DictVo> dictVoMap = DictConfig.DICT_MAPPER.get(value.dictType());
                            if (dictVoMap.isEmpty()) {
                                continue;
                            }
                            // 获取字典值
                            DictVo dictDo = dictVoMap.get(fieldValue.toString());
                            // 获取目标方法进行设值
                            String targetField = StringUtils.isBlank(value.targetField()) ? value.field() : value.targetField();
                            Method targetMethod = voClass.getMethod(SET + firstToUppercase(targetField), dictDo.getClass());
                            targetMethod.invoke(t, dictDo);
                        }
                    } else {
                        // 反射调用get方法获取字段值
                        Method sourceMethod = clazz.getMethod(GET + firstToUppercase(value.field()));
                        Object fieldValue = sourceMethod.invoke(result);
                        // 获取字典值
                        if (Objects.isNull(fieldValue)) {
                            continue;
                        }
                        Map<String, DictVo> dictVoMap = DictConfig.DICT_MAPPER.get(value.dictType());
                        if (dictVoMap.isEmpty()) {
                            continue;
                        }
                        DictVo dictDo = dictVoMap.get(fieldValue.toString());
                        // 获取目标方法进行设值
                        String targetField = StringUtils.isBlank(value.targetField()) ? value.field() : value.targetField();
                        Method targetMethod = clazz.getMethod(SET + firstToUppercase(targetField), dictDo.getClass());
                        targetMethod.invoke(result, dictDo);
                    }
                }
            }
            return result;
        } catch (Throwable throwable) {
            log.error("error:", throwable);
            return null;
        }
    }

    private String firstToUppercase(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

4.具体的字典项返回结果的字典项配置文件

@Component
public class DictConfig {

    public static Map<String, Map<String, DictVo>> DICT_MAPPER = new HashMap<>();

    @Autowired
    private DictDao dictDao;


    @PostConstruct
    public void init() {
        List<DictDo> dictDoList = dictDao.selectList(new LambdaQueryWrapper<>(DictDo.class));
        List<DictVo> dictVoList = BeanCopyUtils.cloneFromList(dictDoList, DictVo.class);
        Map<String, Map<String, DictVo>> resultMap = dictVoList.stream().collect(Collectors.groupingBy(
                DictVo::getDictType, Collectors.toMap(DictVo::getDictValue, Function.identity(), (v1, v2) -> v2)));
        DICT_MAPPER.putAll(resultMap);
    }
}

欢迎大佬给出意见.谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值