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了解的还不是很透彻,如果文章有误的地方,还请指出,感激不尽。

posted on 2018-12-11 22:42  愤怒的苹果ext  阅读(197)  评论(0编辑  收藏  举报

导航