AOP中修改环绕通知返回类型后仍然报错:Null return value from advice does not match primitive return type for

目录

    • 1.具体异常信息:
    • 2.原因分析:
    • 3.解决办法
    • 4.一些更好的解决方案

1.具体异常信息:

org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public abstract boolean com.ssm.service.shopping.ShoppingService.updateShopping(com.ssm.dao.shopping.impl.ShoppingBean)

	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:226)
	at com.sun.proxy.$Proxy21.updateShopping(Unknown Source)
	at com.ssm.test.TestSpringTemplate.testUpdateShoppingService(TestSpringTemplate.java:66)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

2.原因分析:

我的Service返回的是基本类型(primitive)boolean,切面的环绕通知拦截后返回了null,彼此之间不匹配


3.解决办法

修改切面通知的返回值,保持与原始待增强方法返回值一致,这里将返回值的类型修改为Object即可,修改代码如下:

修改aop中的环绕通知

	@Around("allMethod()")
	// 此方法作为环绕通知
	public Object myAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
	// 方法返回值更改为Object
		Object result = null;
		// 定义一个result用于return
		long beginTime=System.currentTimeMillis();
		joinPoint.proceed();
		long endTime=System.currentTimeMillis();
		String targetMethodName=joinPoint.getSignature().getName();
		String logInfoText="环绕通知:"+targetMethodName+"方法调用前时间"+beginTime+"毫秒,"
				+"调用后的时间"+endTime+"毫秒。共执行了"+(endTime-beginTime)+"毫秒。";
		System.out.println(logInfoText);
		return  result;
		// return一个object用于匹配目标方法的返回值
	}

做到这一步,大部分应该都可以正确地跑起来,但是仍然有小部分童鞋还是会报相同的错误,下面才是关键的部分

将返回的Object类型的result,使用joinPoint.proceed()赋值

	@Around("allMethod()")
	// 此方法作为环绕通知
	public Object myAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
		Object result = joinPoint.proceed();
		// 使用joinPoint.proceed()赋值,同时启动目标方法的执行
		long beginTime=System.currentTimeMillis();
		long endTime=System.currentTimeMillis();
		String targetMethodName=joinPoint.getSignature().getName();
		String logInfoText="环绕通知:"+targetMethodName+"方法调用前时间"+beginTime+"毫秒,"
				+"调用后的时间"+endTime+"毫秒。共执行了"+(endTime-beginTime)+"毫秒。";
		System.out.println(logInfoText);
		return  result;
		// return一个object用于匹配目标方法的返回值
	}

4.一些更好的解决方案

  1. 被增强的接口使用包装类返回值,而不是基本类型
  2. 避免在aop期间return

你可能感兴趣的:(笔记)