我有一个 Springboot 应用程序,我正在尝试在 Controller 方法内的 bean 类上执行异步方法。问题是我的 @Async 方法没有异步执行。执行将停止,直到该方法完成。
谁能告诉我我错过了什么?
这是我的应用程序类:
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
connector.setPort(9000);
connector.setAsyncTimeout(60000);
}
});
return factory;
}
}
这是我的 Bean 类:
public class LongProcess {
@Async
public Future<String> call() {
try {
System.out.println("Sleeping now...");
Thread.sleep(10000);
return new AsyncResult<String>("Hey");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
我的配置类:
@Configuration
@EnableAsync
public class LongProcessConfiguration implements AsyncConfigurer {
@Bean
public LongProcess longProcessBean() {
return new LongProcess();
}
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setMaxPoolSize(10);
taskExecutor.setThreadNamePrefix("LULExecutor-");
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}
我的 Controller 方法:
@RequestMapping("/utilities/longProcess")
public String longProcess() {
System.out.println("Starting long process...");
CsvFileDifferConfiguration context = new CsvFileDifferConfiguration();
LongProcess process = context.longProcessBean();
Future<String> result = process.call();
System.out.println("Done!");
return "{success: 1}";
}
不幸的是,这个请求不会立即返回(我不关心结果)。该方法已成功调用,但未在后台调用。知道我可能会错过什么吗?
作为测试,如果我更改 Controller 方法来等待结果,则永远不会进入等待 block :
@RequestMapping("/utilities/longProcess")
public String longProcess() throws InterruptedException {
System.out.println("Starting long process...");
CsvFileDifferConfiguration context = new CsvFileDifferConfiguration();
LongProcess process = context.longProcessBean();
Future<String> result = process.call();
while (!(result.isDone())) {
Thread.sleep(1); //10-millisecond pause between each check
System.out.println("Waiting for Long Process...");
}
System.out.println("Done!");
return "{success: 1}";
}
最佳答案
您的 CDI 使用有误。
如果您使用 Spring 容器管理对象,则必须仅处理 ApplicationContext
或其功能,例如 @Autowired
。
代码
CsvFileDifferConfiguration context = new CsvFileDifferConfiguration();
错误。
由于您将 LongProcess
定义为 @Bean
,因此您可以将其注入(inject)到 @Controller
中:
@Autowired
privete LongProcess process;
并像以前一样使用它。
直接使用对象(例如new
)会失去依赖注入(inject)
功能。
请阅读更多 Spring 文档。
关于java - 为什么我的 Spring @Async bean 方法没有异步执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28944233/