自定义注解+aop实现枚举值转换

自定义注解+aop实现码值转换

实现功能:可以将枚举值转换成枚举类中指定属性值,赋值给返回对象的指定字段上。

准备工作

枚举类

package com.example.service1.common;

public enum SexEnum {

    MAN("0","男","左"),
    WOMAN("1","女","右");

    private String code;

    private String sexName;

    private String fx;

    SexEnum(String code, String sexName, String fx) {
        this.code = code;
        this.sexName = sexName;
        this.fx = fx;
    }

    public static SexEnum getByCode(String code){
        SexEnum[] var1 = values();
        int var2=var1.length;

        for (int var3 = 0; var3 < var2; var3++) {
            SexEnum sexEnums = var1[var3];
            if (sexEnums.code.equals(code)){
                return sexEnums;
            }
        }
        return null;
    }

}

实体类

sql返回对象

package com.example.service1.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;


@Data
@TableName("demo1")
public class Demo1DO implements Serializable {

    @TableId(type = IdType.AUTO)
    private Integer id;

    private String name;

    private String sex;

}

方法返回对象

package com.example.service1.domain;

import com.example.service1.aspect.EnumTrancation;
import com.example.service1.common.SexEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Demo {

    private Integer id;

    private String name;

    @EnumTrancation(enumClass= SexEnum.class,fieldName="sexName",enumFiled="code",enumFieldValue="sexName")
    private String sex;

    private String sexName;
}

自定义注解

package com.example.service1.aspect;

import java.lang.annotation.*;

/**
 * 将枚举码值转换成枚举指定字段内容的注解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnumTrancation {

    /**
     * 使用的枚举类
     * @return
     */
    Class<? extends Enum> enumClass();

    /**
     * 枚举实例的唯一标识
     * @return
     */
    String enumFiled();

    /**
     * 要获取的枚举类实例的的字段
     * @return
     */
    String enumFieldValue();

    /**
     * 接收转换值的字段
     * @return
     */
    String fieldName();


}

aop实现代码

package com.example.service1.aspect;


import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.Collection;

@Component
@Aspect
@Slf4j
public class EnumAspectJ {

    //切入点,这块可以根据自己的需求修改
    @Pointcut("execution(* com.example.service1.service.impl.Demo1ServiceImpl.getByIdIndex(..))")
    public void aspectJPoint(){}

    /**
     * 后置通知:完成枚举转换
     * @param result
     * @return
     */
    @SneakyThrows
    @AfterReturning(pointcut = "aspectJPoint()",returning = "result")
    public Object enumTrancation(Object result){
        if (result instanceof Collection){
            for (Object item  : (Collection<?>)result) {
                enumTrancationCal(item );
            }
        }else {
            enumTrancationCal(result);
        }
        return result;
    }


    /**
     * 完成枚举转换
     * @param result
     * @throws IllegalAccessException
     * @throws NoSuchFieldException
     */
    public void enumTrancationCal(Object result) throws IllegalAccessException, NoSuchFieldException {
        Class<?> resultClass = result.getClass();
        //获取字段列表
        Field[] declaredFields = resultClass.getDeclaredFields();
        //
        for (Field field : declaredFields) {
            field.setAccessible(true);
            EnumTrancation annotation = field.getAnnotation(EnumTrancation.class);
            //如果该字段没有指定注解,则遍历下一个字段
            if (annotation == null){
                continue;
            }
            //有指定注解
            Class<? extends Enum> aClass = annotation.enumClass();
            String fieldName = annotation.fieldName();
            String enumFiled = annotation.enumFiled();
            String enumFieldValue = annotation.enumFieldValue();
            //判断接收翻译值的字段是否存在
            if (!concatField(declaredFields,fieldName)){
                log.info(field.getName()+"字段上"+annotation+"注解配置的接收字段不存在");
                continue;
            }
            Object code = field.get(result);
            //获取code对应的枚举类实例对象
            Enum<?> enumInstance = findEnumInstance(aClass, code, enumFiled);
            //获取枚举类实例对象的enumFieldValue属性值
            Object enumFiledValue = getEnumFiledValue(enumInstance, enumFieldValue);
            //获取要接收字段属性
            Field declaredField = resultClass.getDeclaredField(fieldName);

            declaredField.setAccessible(true);
            declaredField.set(result,enumFiledValue);

        }

        //return result;
    }

    /**
     * 判断字段是否存在
     * @param fields
     * @param fieldName
     * @return
     */
    public boolean concatField(Field[] fields,String fieldName){
        boolean exit=false;
        for (Field field : fields) {
            if (field.getName().equals(fieldName)){
                exit=true;
            }
        }
        return exit;
    }


    /**
     * 获取码值对应的枚举类实例
     * @param enumClass
     * @param code
     * @param codeFieldName
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public Enum<?> findEnumInstance(Class<?> enumClass, Object code,String codeFieldName) throws NoSuchFieldException, IllegalAccessException {
        //遍历枚举类的实例
        for (Object  enumConstant: enumClass.getEnumConstants()) {
            Enum<?> e=(Enum<?>)enumConstant;
            //获取当前遍历到的枚举类实例的codeFieldName字段
            Field declaredField = enumClass.getDeclaredField(codeFieldName);
            declaredField.setAccessible(true);
            //获取当前遍历到的枚举类实例的declaredField字段的值
            Object currentCode = declaredField.get(e);
            //如果当前遍历到的枚举类实例的字段值与code值相等,则返回这个枚举类实例对象
            if (currentCode.equals(code)){
                return e;
            }
        }
        throw new IllegalArgumentException("枚举转换失败: " + code);
    }

    /**
     * 获取枚举类实例的指定属性的值
     * @param enumInstance
     * @param fieldName
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public Object getEnumFiledValue(Enum<?> enumInstance, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        //获取枚举类实例对象的fieldName字段属性
        Field declaredField = enumInstance.getClass().getDeclaredField(fieldName);
        declaredField.setAccessible(true);
        //返回枚举类实例的declaredField字段的值
        return declaredField.get(enumInstance);
    }

}

测试结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值