java - 为什么不能使用spring AOP更改响应类型,除了返回对象
问题描述
我正在使用 Spring AOP 来点切我的控制器方法并尝试将通用结构响应返回到前端。定义应如下所示:
public class CommonResponse {
private String status;
private String message;
private Object data;
}
我还有一个点定义如下:
@Aspect
@Component
public class PostMessageInterceptor {
@Pointcut("within(org.moa.controller.*)")
public void postMessageConvert() {}
@Around("postMessageConvert()")
public CommonResponse modifyResult(ProceedingJoinPoint pjp) {
CommonResponse response = new CommonResponse();
try {
Object result = pjp.proceed();
response.setStatus("success");
response.setData(result);
}catch(Throwable t) {
response.setStatus("failure");
response.setMessage(t.getMessage());
}
return response;
}
}
例如,当控制器返回类型中的方法为 时Map<String,String>
,modifyResult
执行后返回类型已转换为CommonResponse
from Map<String,String>
,则 Spring AOP 将发生异常java.lang.ClassCastException: CommonResponse cannot be cast to java.util.Map
如果我将此方法的返回类型更改为 Object,它将正常工作。
我只是想这是这样设计的吗?否则,有什么方法可以在不将返回类型修改为 Object 的情况下实现此目标。因为感觉很奇怪,所有方法都返回相同类型的 Object。
解决方案
您不能更改被包围方法的返回类型。JVM 的机制不允许这样做(请参阅此问题的答案)。
您的方法的调用者根据原始方法的接口编译他的代码,但是在执行您的 adivice 之后,该方法返回了不同的类型。那应该如何工作?
一种可能性是使用接口并返回由您的建议创建的不同实现,例如:
interface MyReturnType {
int getStatus();
Map<String, String> getData();
}
class MethodReturnType implements MyReturnType {
int getStatus() { throw NotImplementedException(); }
// should never be called; every other method in the interface can be implemented in the exact same way
Map<String, String> getData() { return data; } // I omit the constructor and field decleration here
}
class AdviceReturnType implements MyReturnType {
int status;
Map<String, String> data;
int getStatus() { return status; }
Map<String, String> getData() { return data; }
}
public MyReturnType myAdvicedMethod(...) {
// ...
return new MethodReturnType(myCalculatedData);
}
public Object aroundAdvice(ProceedingJoinPoint pjp) {
MyReturnType retVal = (MyReturnType) pjp.proceed();
// calculate status and stuff
return new AdviceReturnType(retVal.getData(), caluclatedStatus, ...);
}
推荐阅读
- css - CSS - @media 屏幕和(最大宽度:---px)在 Firefox 移动设备上不起作用
- javascript - 如何在异步函数中实现 Promise 的结果?
- android - Android Studio - CMake 错误:CMake 无法找到与“Ninja”对应的构建程序。CMAKE_MAKE_PROGRAM 未设置
- node.js - 为每个用户 nodejs 渲染信息
- c# - Oracle Advanced Queue 的消息状态在使用 ODP.net 出队后未更新
- weka - 显示加权平均的问号。weka中的精度
- for-loop - 为什么循环范围内没有增量,其范围是循环的长度,即使长度在循环内增加?
- mongodb - Mongodb 按功能分组,提供意外数据
- pandas - 如何将 pandas.DataFrame 中的多个(所有)列直接堆叠在一个列中?
- java - Java 的速度几乎是 Rust 的两倍?!?我错过了什么?