P_M
P_M

Reputation: 2942

Spring boot. How to Create TaskExecutor with Annotation?

I did a @Service class in Spring Boot application with one of the methods that should run asynchronously. As I read method should be @Async annotated and also I have to run a TaskExecutor bean. But in Spring manual http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html I not find any info or example how to run TaskExecutor with annotation, without XML config. Is it possible to create TaskExecutor bean in Spring Boot without XML, with annotations only? Here my Service class:

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

Upvotes: 32

Views: 70218

Answers (3)

Derlin
Derlin

Reputation: 9891

UPDATE: as of Spring Boot 2.1, there is no need to create the ThreadPoolTaskExecutor through code, since ThreadPoolTaskExecutor is the default and can be completely configured using properties prefixed with spring.task.execution.

So, steps:

  1. use @EnableAsync in a @Configuration-annotated class,
  2. annotate one or more methods with @Async
  3. optionally override the default ThreadPoolTaskExecutor config with properties

Properties example:

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

If more customization is required, one can also implement the TaskExecutorCustomizer interface, for example (in kotlin):

@Component
class AsyncExecutorCustomizer : TaskExecutorCustomizer {
    override fun customize(taskExecutor: ThreadPoolTaskExecutor?) {
        taskExecutor?.let { executor ->
            executor.setRejectedExecutionHandler(ThreadPoolExecutor.CallerRunsPolicy())
        }
    }
}

Upvotes: 16

Jesper
Jesper

Reputation: 206786

Add a @Bean method to your Spring Boot application class:

@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) {
        // ...
    }
}

See Java-based container configuration in the Spring Framework reference documentation on how to configure Spring using Java config instead of XML.

(Note: You don't need to add @Configuration to the class because @SpringBootApplication already includes @Configuration).

Upvotes: 52

Igor Shevchenko
Igor Shevchenko

Reputation: 141

First – let’s go over the rules – @Async has two limitations:

  • it must be applied to public methods only
  • self-invocation – calling the async method from within the same class – won’t work

So your processPage() method should be in separate class

Upvotes: 14

Related Questions