自定义注解+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);
}
}