Spring Boot异步基于接口的控制器不起作用

时间:2018-06-27 08:44:31

标签: java spring spring-boot

我在Spring boot 2.0中发现了这个问题(或没有问题?)。

@Async("someWorker")
public CompletableFuture<CreateAuthorResponse> authorPost(@RequestBody CreateAuthorRequest request)
        throws Exception {
    CompletableFuture<CreateAuthorResponse> future = new CompletableFuture<>();
    future.complete(authorDao.createAuthor(request.getFirstName(), request.getLastName()));
    return future;
}

接口是:

@RequestMapping(value = "/library/authors", method = RequestMethod.POST)
public CompletableFuture<CreateAuthorResponse> authorPost(@RequestBody CreateAuthorRequest request)
        throws Exception;

由于 AbstractHandlerMethodMapping.class

中的以下代码,在请求映射中找不到该控制器
protected void initHandlerMethods() {
        if (logger.isDebugEnabled()) {
            logger.debug("Looking for request mappings in application context: " + getApplicationContext());
        }
        String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
                BeanFactoryUtils.beanNamesForTypeIncludingAncestors(obtainApplicationContext(), Object.class) :
                obtainApplicationContext().getBeanNamesForType(Object.class));

        for (String beanName : beanNames) {
            if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
                Class<?> beanType = null;
                try {
                    beanType = obtainApplicationContext().getType(beanName);
                }
                catch (Throwable ex) {
                    // An unresolvable bean type, probably from a lazy bean - let's ignore it.
                    if (logger.isDebugEnabled()) {
                        logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
                    }
                }
                if (beanType != null && isHandler(beanType)) {
                    detectHandlerMethods(beanName);
                }
            }
        }
        handlerMethodsInitialized(getHandlerMethods());
    }

beanType 是com.sun.proxy。$ Proxy类,但不是CGLIB代理,并且 isHandler 从sun.proxy中找不到任何注释,但在CGLIB中可以正常工作代理。

@EnableAsync(proxyTargetClass = true)强制每个操作到CGLIB可以解决此问题。删除接口也可以解决此问题。但是,如果仅使用 @EnableAsync ,则无法在spring之前找到控制器。

@RestController
@Validated
public class LibraryControllerImpl {
    @Autowired
    AuthorDao authorDao;

    @Async("someWorker")
    @RequestMapping(value = "/library/authors", method = RequestMethod.POST)
    public CompletableFuture<CreateAuthorResponse> authorPost(@RequestBody CreateAuthorRequest request)
        throws Exception {
        CompletableFuture<CreateAuthorResponse> future = new CompletableFuture<>();
        future.complete(authorDao.createAuthor(request.getFirstName(), request.getLastName()));
    return future;
}
  

2018-06-27 16:35:02.376信息150160 --- [main] swsmmaRequestMappingHandlerMapping:将“ {[/ library / authors],methods = [POST],consumes = [application / json]}映射到公共java.util.concurrent.CompletableFuture LibraryControllerImpl.authorPost(CreateAuthorRequest)抛出java.lang.Exception

0 个答案:

没有答案