注:本文所示代码需要根据自己的业务进行修改
一 .背景:由于在某些特殊场合,用户,部门,等等,在画面中显示的是数字,而不是对应的名称,进行在切面的补充。
所用环境 JDK 17
所用框架 springboot 3
所用技术 Aspect 切面
两个方案:
1.手写方法,进行调用进行字段的补充
2.使用Aspect对Controller进行切面,拿到对应的返回结果,对返回结果进行处理
第一个方案,感觉太麻烦,需要在每一个需要补充字段的时候进行调用,如果忘记补充,则会被挨P,所以我没选择这种方式。
着重讲一下 第二种方案 :
①首先需要创建在字段上标注的注解
AutoFillType :根据业务进行区分,把需要补充不同的信息,区分开
fillName :需要补充的字段
/**
* 自动补充字段注解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
/**
* 补充字段类型
*/
AutoFillType value();
/**
* 补充字段名称
*/
String fillName();
}
建立对应的枚举继续,区分
public enum AutoFillType {
// 部门
DEPT ,
// 用户
USER ,
// 角色
ROLE
}
②创建对应的Aspect类
关键点:
需要判断 字段上是否有 @AutoFill 注解
@AfterReturning(value = "autoFillPointCut()" , returning = "result") 获取运行成功后的返回结果 因为返回结果通常会包一层,需要得到最终需要补充的类进行补充,所以需要 instanceof 根据本身的代码进行修改 这个时候就可以用 AutoFillType 进行区分业务上的补充字段
/**
* 自定义切面类,实现公共字段的填充
*/
@Component
@Aspect
public class AutoFillAspect {
/*
切入点
*/
@Pointcut("execution(* org.xx.controller.*.*(..) )")
public void autoFillPointCut() {
}
@AfterReturning(value = "autoFillPointCut()" , returning = "result")
public void autoFill(JoinPoint joinPoint , Object result) {
// 获取返回对象
if (result instanceof R r){
Object sourceData = r.getData();
if (sourceData instanceof List data){
if (data.isEmpty()) return;
// 遍历 返回参数
for (Object datum : data) {
// 获取字段注解
for (Field field : datum.getClass().getDeclaredFields()) {
if (!field.isAnnotationPresent(AutoFill.class)) continue;
field.setAccessible(true);
// 获取指定注解
AutoFill annotation = field.getAnnotation(AutoFill.class);
// 获取 当前注解下的字段值
Object fieldValue = ReflectionUtil.getFieldValue(datum, field.getName());
if (fieldValue == null) continue;
Long id = Long.valueOf(fieldValue.toString());
// 需要补充的字段
String fillName = annotation.fillName();
// 需要补充的类型
AutoFillType value = annotation.value();
switch (value){
case USER -> {
User user = UserCache.getUser(id);
ReflectionUtil.setFieldValue(datum,fillName,user.getName());
}
case DEPT -> {
Dept dept = SysCache.getDept(id);
ReflectionUtil.setFieldValue(datum,fillName,dept.getDeptName());
}
case ROLE -> {
Role role = SysCache.getRole(id);
ReflectionUtil.setFieldValue(datum,fillName,role.getRoleName());
}
default -> {
}
}
}
}
}
}
}
③最后在Controller 返回的参数里面 加上创建的注解 进行补充
补充类型是 USER 就是就是补充用户的信息 ,补充信息到 approvalUserName 字段上
/**
* 审批人
*/
@AutoFill(value = AutoFillType.USER , fillName = "approvalUserName")
private Long approvalUser;
private String approvalUserName;
随着业务的复杂度,扩充对应的注解字段,进行多种补充逻辑。