According to Spring's documentation the way to use the TaskExecutor is as follows:
import org.springframework.core.task.TaskExecutor;
public class TaskExecutorExample {
private class MessagePrinterTask implements Runnable {
private String message;
public MessagePrinterTask(String message) {
this.message = message;
}
public void run() {
System.out.println(message);
}
}
private TaskExecutor taskExecutor;
public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask("Message" + i));
}
}
}
However, if MessagePrinterTask has autowired dependencies they will not be configured by Spring because we are instantiating our bean outside of Spring's context (at least that's how I understand it) even though Spring will provide the actual thread creation. If MessagePrinterTask were to have autowired dependencies how do we get Spring to recognize them? I tried the following modified example to no avail (and yes, autowiring is enabled properly):
import org.springframework.core.task.TaskExecutor;
public class TaskExecutorExample {
@Component
private class MessagePrinterTask implements Runnable {
@Autowired
private autoWiredDependency;
public void run() {
autoWiredDependency.doNotThrowNullPointerExceptionPlease();
}
}
private TaskExecutor taskExecutor;
public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask());
}
}
}
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.
The answer for your question is YES. You can use autowired in thread class.
The TaskExecutor was originally created to give other Spring components an abstraction for thread pooling where needed. Components such as the ApplicationEventMulticaster , JMS's AbstractMessageListenerContainer , and Quartz integration all use the TaskExecutor abstraction to pool threads.
Spring @Autowired Annotation - Service ClassThe setter method will be used for spring autowiring byName and byType whereas constructor based injection will be used by constructor autowire attribute.
There are two ways I think that you can go about this:
a. Provide the dependencies to the Task - this way:
class MessagePrinterTask implements Runnable {
public MessagePrinterTask(ADependency aDependency){
this.aDependency = aDependency;
}
private ADependency aDependency;
public void run() {
aDependency.doNotThrowNullPointerExceptionPlease();
}
}
And in your TaskExectorExample which can be the singleton:
import org.springframework.core.task.TaskExecutor;
public class TaskExecutorExample {
@Autowired private ADependency aDependency;
@Autowired
public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask(this.aDependency));
}
}
}
b. Using @Configurable annotation on your MesasgePrinterTask, this will inject in dependencies into MessagePrinterTask even though it is instantiated outside of a Spring Container - there are some catches in using @Configurable though(requires AspectJ):
@Configurable
class MessagePrinterTask implements Runnable {
You can also use the @Async annotation.
public class TaskExecutorExample {
@Autowired
private MessagePrinterTask task;
public void printMessages() {
for(int i = 0; i < 25; i++) {
task.printMessage();
}
}
}
@Component
public class MessagePrinterTask implements Runnable {
@Autowired
private String message;
@Async
public void printMessage() {
System.out.println(message);
}
}
Any call to printMessage() will be executed asynchronously using a default executor, which you can configure using the following in your Spring xml config.
<task:annotation-driven executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="5" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With