java - Spring 引导应用程序无法“自动装配”作为新线程代理的服务类
问题描述
我正在使用Spring Boot
[v. 2.1.4.RELEASE] 和@Async
注释一起CompletableFuture
以实现异步和非阻塞调用。
我已经实现了一个用于运行TaskExecutor
将提供多线程环境的 Config 类,以及一对实现 POST 请求的 Service-Controller 类。
配置
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Bean(name = "musterExecutor")
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("AppExecutor-");
executor.initialize();
return new ThreadPoolTaskExecutor();
}
}
一个服务类,其中Status
是用于映射响应的 pojo。
服务
@Service
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class MusterService<T> {
private static final String request_status = RestURIConstants.STATUS;
private static final String request_execution = RestURIConstants.EXECUTE;
private static final String request_async = Constants.ASYNC;
private static final String DATA_FUSION = Constants.DATA_FUSION;
@Autowired
private RestTemplate restTemplate;
@Async("musterExecutor")
public CompletableFuture<Status> execute(Payload payload) {
HttpHeaders headers = setHeaders();
String input = Constructor.createPayload(payload);
HttpEntity<String> requestEntity = new HttpEntity<String>(input, headers);
Status s = restTemplate.postForObject(execution_url, request_execution, Status.class);
return CompletableFuture.completedFuture(s);
}
@Async("musterExecutor")
public CompletableFuture<Status[]> getStatus() {
log.debug("Sending Status Request");
final String status_url = request_status;
HttpHeaders headers = setHeaders();
HttpEntity<String> requestEntity = new HttpEntity<String>(request_async, headers);
Status[] s = restTemplate.postForObject(status_url, requestEntity, Status[].class);
return CompletableFuture.completedFuture(s);
}
private HttpHeaders setHeaders() {
// code for setting the Headers
return headers;
}
}
连同一个简单的
服务接口
public interface GenericService<T> {
public abstract CompletableFuture<Status[]> getStatus();
public abstract CompletableFuture<Status> execute(Payload payload);
}
控制器
@RestController
@RequestMapping(path = "/api")
public class MusterController {
@Autowired
private MusterService<Status> musterService;
@RequestMapping(value = "/status", method = RequestMethod.GET)
@ResponseBody
public CompletableFuture<Status[]> status() {
CompletableFuture<Status[]> cf_status = new CompletableFuture<Status[]>();
try {
cf_status = musterService.getStatus();
return cf_status;
} catch (RestClientException e) {
e.printStackTrace();
// TODO: handle exception
}
return cf_status;
}
@RequestMapping(value = "/execute", method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
@ResponseBody
public CompletableFuture<Status> execute(@RequestBody Payload payload) throws SchedulerException, IOException {
CompletableFuture<Status> cf_execution_body = new CompletableFuture<Status>();
Status execution_body = new Status();
try {
cf_execution_body = musterService.execute(payload);
execution_body = cf_execution_body.get();
return cf_execution_body;
} catch (RestClientException e) {
log.error("RestClientException:{} \t Cause:{}", e.getMessage(), e.getCause());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return cf_execution_body;
}
}
为了启动线程,该类的实例被正确代理,但是当我尝试implement
使用接口类(又名public class MusterService<T> implements GenericService<T>
..)的服务类时,它给了我以下错误:
引起:org.springframework.beans.factory.BeanNotOfRequiredTypeException
服务被代理为新线程,由于某种原因无法自动装配
当我删除implements
然后一切都按预期工作。
注意:我已@EnableAspectJAutoProxy(proxyTargetClass = true)
添加注释以使其按建议工作,但它没有做任何事情。我怎样才能让它工作?
堆栈溢出参考:
解决方案
这@EnableAsync
导致MusterService
被代理,因此它的@Async
方法可以是异步的。默认情况下,@EnableAsync
如果被代理的类实现单个接口,将创建 JDK 代理。MusterService
实现时就是这种情况GenericService
。因此,必须将集合服务 bean 作为代理使用,GenericService
因为这是代理遵守的合同。
如果您希望您的控制器能够注入一个MusterService
实例,您应该修改@EnableAsync
为使用 CGLib 代理:
@EnableAsync(proxyTargetClass = true)
推荐阅读
- java - axios.post("/checkitem/add.do",this.formData).then((res)....得到 404
- flutter - 具有共享偏好的 Flutter Switch 在第一次更改时不起作用
- ios - 显示EditText的键盘后视图不滚动(在键盘下编辑文本)SwiftUI
- node.js - Google Speech Adaptation Client (node.js) - UnhandledPromiseRejectionWarning:错误:13 内部:遇到内部错误
- python - 将情节静态图像生成从逆戟鲸更改为万花筒
- node.js - 如何在 Elasticsearch 中为文件夹中的每个文件获取一个新的 JSON 条目
- ios - 为什么我们可以将 flatMap 链接到 UserDefaults.standard.data
- excel - Excel中的外部引用字符串仅在从开头删除'后才变为公式,为什么以及如何重复数百次?
- python - TypeError:recognize() 接受 1 到 2 个位置参数,但给出了 3 个
- typescript - 如何通过 Jest 的异步方法测试