AopInvocationException:Null return value from advice does not match primitive...

192 阅读1分钟

这个异常出现在我在程序里面使用了@[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类型就可以了。