我在Spring Boot应用程序中执行了一个@Service
类,其中一个方法应该异步运行。因为我读取方法应该@Async
注释,我还必须运行TaskExecutor
bean。但是在Spring手册中http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html我没有找到任何信息或示例如何在没有XML配置的情况下运行带有注释的TaskExecutor
。是否可以在没有XML的情况下在Spring Boot中创建TaskExecutor
bean,仅注释?这是我的服务类:
@Service
public class CatalogPageServiceImpl implements CatalogPageService {
@Override
public void processPagesList(List<CatalogPage> catalogPageList) {
for (CatalogPage catalogPage:catalogPageList){
processPage(catalogPage);
}
}
@Override
@Async("locationPageExecutor")
public void processPage(CatalogPage catalogPage) {
System.out.println("print from Async method "+catalogPage.getUrl());
}
}
答案 0 :(得分:33)
在Spring Boot应用程序类中添加@Bean
方法:
@SpringBootApplication
@EnableAsync
public class MySpringBootApp {
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(25);
return executor;
}
public static void main(String[] args) {
// ...
}
}
请参阅Spring Framework参考文档中的Java-based container configuration,了解如何使用Java配置而不是XML配置Spring。
(注意:您无需在课程中添加@Configuration
,因为@SpringBootApplication
已包含@Configuration
)。
答案 1 :(得分:6)
首先 - 让我们回顾一下规则 - @Async有两个限制:
所以你的processPage()方法应该在单独的类
中答案 2 :(得分:1)
更新:从 Spring Boot 2.2 开始,无需通过代码创建ThreadPoolTaskExecutor
。实际上, ThreadPoolTaskExecutor
是默认设置,并且可以使用前缀为spring.task.execution
的属性进行完全配置。
因此,执行以下步骤:
@EnableAsync
注释的类中使用@Configuration
,@Async
注释一种或多种方法ThreadPoolTaskExecutor
配置属性示例:
spring.task.execution.pool.core-size=1
spring.task.execution.pool.max-size=20
spring.task.execution.pool.keep-alive=120s
spring.task.execution.pool.queue-capacity=1000
spring.task.execution.shutdown.await-termination=true
spring.task.execution.shutdown.await-termination-period=5m
spring.task.execution.thread-name-prefix=async-executor-
spring.task.execution.pool.allow-core-thread-timeout=false
如果需要更多自定义,则还可以实现TaskExecutorCustomizer
接口,例如(在kotlin中):
@Component
class AsyncExecutorCustomizer : TaskExecutorCustomizer {
override fun customize(taskExecutor: ThreadPoolTaskExecutor?) {
taskExecutor?.let { executor ->
executor.setRejectedExecutionHandler(ThreadPoolExecutor.CallerRunsPolicy())
}
}
}