1.编写字段属性的自定义注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictParam {
/**
* 映射目标属性,为空默认直接映射到field,替换掉原来的field
*
* @return
*/
String targetField() default "";
/**
* 映射来源属性
*
* @return
*/
String field();
/**
* 数据字典类型
*
* @return
*/
String dictType();
}
2.具体AOP实现
@Slf4j
@Aspect
@Component
public class DictAspect {
public static final String GET = "get";
public static final String SET = "set";
@Pointcut("@annotation(com.citycloud.bigdata.biz.clearance.common.dict.DictParam)")
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(DictParam.class)) {
DictParam dictParam = method.getAnnotation(DictParam.class);
String oldDictType = dictParam.dictType();
String oldField = dictParam.field();
String oldTargetField = dictParam.targetField();
// 字典转换开始(使用反射)
Class<?> clazz = result.getClass();
// 反射调用get方法获取字段值
Method sourceMethod = clazz.getMethod(GET + firstToUppercase(oldField));
Object fieldValue = sourceMethod.invoke(result);
if(Objects.isNull(fieldValue)){
return result;
}
// 获取字典值
Map<String, DictVo> dictVoMap = DictConfig.DICT_MAPPER.get(oldDictType);
if(dictVoMap.isEmpty()){
return result;
}
DictVo dictDo = dictVoMap.get(fieldValue.toString());
// 获取目标方法进行设值
String targetField = StringUtils.isBlank(oldTargetField) ? oldField : oldTargetField;
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);
}
}
3.数据字典初始化
@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);
}
}
4.字段上具体添加的注解