Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autowiring Tasks sent to Spring TaskExecutor

Tags:

java

spring

How can you have a class that implements Runnable and submitted to springs TaskExecutor autowired?

For example, I have a Task:

public class MyTask implements Runnable {

    @Autowired private MyRepository myRepository;

    @Override
    public void run() {
        myRepository.doSomething();
    }
}

And a service that sends a task to the spring TaskExecutor:

@Service
public class MyService {

    @Autowired private TaskExecutor taskExecutor;

    public void someMethod() {

        MyTask myTask = new MyTask();
        taskExecutor.execute(myTask);

    }

}

I know the fields aren't being autowired because MyTask is getting instantiated using new MyTask(). However, how do I get around this? Should I be getting access to Spring's ApplicationContext and create the bean through it? How would you do this in a web application environment?

Thanks!

like image 629
Brian DiCasa Avatar asked Apr 18 '13 22:04

Brian DiCasa


People also ask

What is the use of TaskExecutor in Spring?

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.

What is TaskExecutor?

Interface TaskExecutorSimple task executor interface that abstracts the execution of a Runnable . Implementations can use all sorts of different execution strategies, such as: synchronous, asynchronous, using a thread pool, and more.


1 Answers

try

public class MyTask implements Runnable {
    private MyRepository myRepository;

    public MyTask(MyRepository myRepository) {
         this.myRepository = myRepository;
    }

    @Override
    public void run() {
        myRepository.doSomething();
    }
}

@Service
public class MyService {
    @Autowired private TaskExecutor taskExecutor;
    @Autowired private MyRepository myRepository;


    public void someMethod() {
        MyTask myTask = new MyTask(myRepository);
        taskExecutor.execute(myTask);
    }
}

or you can declare MyTask's scope = "prototype" and change MyService as

@Service
public class MyService {
    @Autowired private ApplicationContext ctx;

    public void someMethod() {
        MyTask myTask = ctx.getBean(MyTask.class);
        taskExecutor.execute(myTask);
    }
}
like image 54
Evgeniy Dorofeev Avatar answered Oct 13 '22 20:10

Evgeniy Dorofeev