Peeeeeeek Peeeeeeek - 13 days ago 5
Java Question

Cannot get Spring-MVC @Async to go to a different thread

I am trying to get a method to run async in my Spring MVC web application.
I have added these lines to my config.

<!-- Enable Scheduling/Async Annotations -->
<task:executor id="villageExecutor" pool-size="5"/>
<task:scheduler id="villageScheduler" pool-size="5"/>
<task:annotation-driven executor="villageExecutor" scheduler="villageScheduler" />


I've added the @Async to my method like so;

@Component
public class OutstandingBreakdownDownload {
private static Logger logger = Logger.getLogger(OutstandingBreakdownDownload.class.getName());

@Async
public void execute(String companyNumber) {
System.out.println("Execute method asynchronously. " + Thread.currentThread().getName());


And I am calling this method from a servlet like so;

System.out.println("Initial thread. " + Thread.currentThread().getName());
new OutstandingBreakdownDownload().execute(companyNumber);


When I check the logs the thread the servlet is running in is the same as the thread the @Async method is running. I see no error messages at all.
I also use the @Schedule annotation and this works correctly as I see those running in villageSheduler threads.

This is the output from the console when I call the @Async method.

Initial thread. http-bio-8080-exec-10
Execute method asynchronously. http-bio-8080-exec-10


Can anyone see what I am doing wrong?

Answer

Don't create the objects using new for the classes which are annotated with @Component, @Controller, @Service as the objects (by default singleton scope) are managed/injected by the Spring container.

Rather, in your servlet class, add @Autowired for OutstandingBreakdownDownload so that Spring container can run the Async method in a separate thread.

public class Servlet ... {

   @Autowired
   private OutstandingBreakdownDownload downloadBean;

   //your methods
   public R method1() {
     downloadBean.execute();
  }
}