我在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