场景模拟
1. 基础场景搭建
@Data
public class UpdateOrder {
private Long orderId;
}
@Data
public class SaveOrder {
private Long id;
}
@Service
public class OrderService {
public Boolean saveOrder(SaveOrder saveOrder) {
System.out.println("保存订单, orderId: " + saveOrder.getId());
return true;
}
public Boolean updateOrder(UpdateOrder updateOrder) {
System.out.println("更新订单, orderId: " + updateOrder.getOrderId());
return true;
}
}
测试
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) {
new SpringApplication(Application.class).run(args);
}
@Autowired
private OrderService orderService;
@Override
public void run(String... args) throws Exception {
SaveOrder saveOrder = new SaveOrder();
saveOrder.setId(1L);
orderService.saveOrder(saveOrder);
UpdateOrder updateOrder = new UpdateOrder();
updateOrder.setOrderId(2L);
orderService.updateOrder(updateOrder);
}
}
2. AOP 实现
2.1 自定义注解
public @interface RecordOperate {
String desc() default "";
}
2.2 在需要增强的方法上加上注解
2.3 定义切面
@Component
@Aspect
public class OperateAspect {
@Pointcut("@annotation(RecordOperate)")
public void pointcut(){}
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
Object result = point.proceed();
// 待填写
return result;
}
}
问
不同的入参
private Long orderId;
private Long id;
在统一的切面中,如何根据不同的入参,获取到想要的参数
难道要一个一个判断吗?
解决方法
定义一个接口,根据指定方法进行转换,根据不同的入参,拿到标准模型
实现
定义统一返回
@Data
public class OperateLogDO {
private Long orderId;
private String desc;
private String result;
}
定义接口
public interface Convert <PARAM>{
OperateLogDO convert(PARAM param);
}
修改注解
public @interface RecordOperate {
String desc() default "";
Class<? extends Convert> convert();
}
定义一个类去实现Convert 接口 完成对数据的处理
public class SaveOrderConvert implements Convert<SaveOrder>{
@Override
public OperateLogDO convert(SaveOrder saveOrder) {
OperateLogDO operateLogDO = new OperateLogDO();
operateLogDO.setOrderId(saveOrder.getId());
return operateLogDO;
}
}
完善切面OperateAspect
MethodSignature methodSignature = (MethodSignature) point.getSignature();
RecordOperate annotation = methodSignature.getMethod().getAnnotation(RecordOperate.class);
Class<? extends Convert> convert = annotation.convert();
Convert logConvert = convert.newInstance();
OperateLogDO operateLogDO = logConvert.convert(point.getArgs()[0]);
operateLogDO.setDesc(annotation.desc());
operateLogDO.setResult(result.toString());
System.out.println("新增日志 " + JSON.toJSONString(operateLogDO));
完善增强方法上的注解
@RecordOperate(desc = "保存订单", convert = SaveOrderConvert.class)
public Boolean saveOrder(SaveOrder saveOrder) {
System.out.println("保存订单, orderId: " + saveOrder.getId());
return true;
}
结尾
这样以后来的新的方法只需要实现 Convert 接口,就不需要去改老的代码啦!