I would like to start an asynchronous task from within controller like in following code sniplet from Spring docs.
import org.springframework.core.task.Tas
One solution could be: in your async thread, write to a DB, and have your checking code check the DB table for progress. You get the additional benefit of persisting performance data for later evaluation.
Also, just use the @Async
annotation to kick off the asynchronous thread - makes life easier and is a Spring Way To Do It.
Have you looked at the @Async
annotation in the Spring reference doc?
First, create a bean for your asynchronous task:
@Service
public class AsyncServiceBean implements ServiceBean {
private AtomicInteger cn;
@Async
public void doSomething() {
// triggers the async task, which updates the cn status accordingly
}
public Integer getCn() {
return cn.get();
}
}
Next, call it from the controller:
@Controller
public class YourController {
private final ServiceBean bean;
@Autowired
YourController(ServiceBean bean) {
this.bean = bean;
}
@RequestMapping(value = "/trigger")
void triggerAsyncJob() {
bean.doSomething();
}
@RequestMapping(value = "/status")
@ResponseBody
Map<String, Integer> fetchStatus() {
return Collections.singletonMap("cn", bean.getCn());
}
}
Remember to configure an executor accordingly, e.g.
<task:annotation-driven executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="5"/>
Check this github source, it gives pretty simple way of catching status of the background job using @Async of Spring mvc.
https://github.com/frenos/spring-mvc-async-progress/tree/master/src/main/java/de/codepotion/examples/asyncExample
Ignoring synchronization issues you could do something like this:
private class MessagePrinterTask implements Runnable {
private int cn;
public int getCN() {
return cn;
}
...
}
public class TaskExecutorExample {
MessagePrinterTask printerTask;
public void printMessages() {
printerTask = new MessagePrinterTask();
taskExecutor.execute(printerTask);
}
...
}