这个异常出现在我在程序里面使用了@[Async] 或者 @Around 、@before、@after 等通知切面的时候。
@Bean("provinceServiceExecutor")
public Executor provinceServiceExecutor() {
//ThreadPoolExecutor是线程池的真正实现,他通过构造方法的一系列参数,来构成不同配置的线程池
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// ExecutorService service = Executors.newCachedThreadPool();//包含2个线程对象
//配置核心线程数
executor.setCorePoolSize(10);
//配置最大线程数
executor.setMaxPoolSize(300);
//配置队列大小
executor.setQueueCapacity(999999);
//线程池维护线程所允许的空闲时间
executor.setKeepAliveSeconds(600);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix("async-service-");
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
这段代码是我在程序启动的时候创建了[线程池]。下面代码是调用。
@Async("provinceServiceExecutor")
public boolean provinceCityInsert(ProvinceCityDTO inDTO) {
boolean result = provinceCityManager.provinceCityInsert(inDTO);
if (result) {
log.info("省市区县信息推送到mq-Start" + inDTO.getRequestNo());
List<ProvinceCityDTO.ProvinceCityInDTO> list = inDTO.getList();
String context = JSON.toJSONString(list);
callBackSenderServer.provinceSend(context, mqQueueProperties.getRkprovince());
log.info("省市区县信息推送到mq-End" + inDTO.getRequestNo());
}
return result;
}
我们从上面可以看出来异步标签调用返回的类型是Executor,而下面程序注解标注的方法则返回的是boolean。这样导致一个返回结果的类型不一致。
所以会报如下错误:
org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public abstract boolean com.yonyou.dcep.dms.tds.sales.product.service.ProductService.productInfoSend(com.yonyou.dcep.dms.tds.sales.product.dto.in.ProductInfoInDTO)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:226)
at com.sun.proxy.$Proxy213.productInfoSend(Unknown Source)
at com.yonyou.dcep.dms.tds.sales.product.controller.ProductController.add(ProductController.java:47)
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:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:891)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
所以我们就把boolean类型改成Object类型就可以了。