spring aop Null return value from advice does not match primitive return type for总结
- Null return value from advice does not match primitive return type for这个一般都是发生在代码做了环绕后。
- 找到源码抛出这个异常的位置(我是全局搜索的我使用的cglib动态代理的代码)CglibAopProxy#processReturnType:
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
// Massage return value if necessary
if (retVal != null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this". Note that we can't help
// if the target sets a reference to itself in another returned object.
retVal = proxy;
}
Class<?> returnType = method.getReturnType();
//isPrimitive 此方法主要用来判断Class是否为原始类型(boolean、char、byte、short、int、long、float、double)。 returnType != Void.TYPE 是否是无返回值类型
if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
- 出现异常情况的第一种情况:
比如我的环绕代码是这样的:
//环绕service里的方法
@Around("execution(* com.zzq.core.test.service..*.*(..))")
public void around(ProceedingJoinPoint pjp ){
System.out.println("AOP Aronud before...");
Object result = null;
try {
result = pjp.proceed();
System.out.println("result : "+ result);
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("AOP Aronud after...");
}
service是这样的:
@Override
public int select(int id) {
System.out.println("Enter DaoImpl.select() " + id);
return 1;
}
此时抛出异常:
Exception in thread "main" org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public int com.zzq.core.test.service.impl.TestAopServiceImpl.select(int)
at org.springframework.aop.framework.CglibAopProxy.processReturnType(CglibAopProxy.java:351)
at org.springframework.aop.framework.CglibAopProxy.access$0(CglibAopProxy.java:341)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:636)
at com.zzq.core.test.service.impl.TestAopServiceImpl$$EnhancerBySpringCGLIB$$1f185468.select(<generated>)
at com.zzq.core.test.BootStrap.main(BootStrap.java:18)
因为环绕没有返回值为null,select方法返回类型不是void ,而是int,刚好满足条件,抛出此异常。int是无法匹配null的(除非是包装类型Integer,不过接到的一直是null)。
还是需要改环绕,加上返回值就不报错了:
@Around("execution(* com.zzq.core.test.service..*.*(..))")
public Object around(ProceedingJoinPoint pjp ){
System.out.println("AOP Aronud before...");
Object result = null;
try {
result = pjp.proceed();
System.out.println("result : "+ result);
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("AOP Aronud after...");
return result;
}
- 报错情况二、
结合上面的加上返回值还是报错,那么应该是代理的方法报错了,比如上面的select方法报错了也会报Null return value from advice does not match primitive return type for
比如这样的:
@Override
public int select(int id) {
int a = 1 / 0;
System.out.println("Enter DaoImpl.select() " + id);
return 1;
}
代理的方法select方法肯定报错,执行被代理方法try catch了,报错后没接收到代理方法的返回值也属正常,返回null,抛出异常。
目前我对aop了解的还不是很透彻,如果文章有误的地方,还请指出,感激不尽。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现