春天的靴子。如何使用注释创建TaskExecutor?

时间:2016-07-14 09:09:40

标签: java spring asynchronous concurrency

我在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());
    }
}

3 个答案:

答案 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的属性进行完全配置。

因此,执行以下步骤:

  1. 在带有@EnableAsync注释的类中使用@Configuration
  2. 使用@Async注释一种或多种方法
  3. (可选)使用属性覆盖默认的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())
        }
    }
}