Since Spring 3.2 it should be possible to use a qualifier in the “Async” annotation of a method, to indicate which specific executor to use. For example, I have the following class, that is supposed to collect the HTML from a website asynchronously:

HTMLFetcher Interface

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.concurrent.Future;

import org.springframework.scheduling.annotation.Async;

public interface HTMLFetcher {

Future<HTMLFetcher.HTMLFetcherResult> getHTML(String baseUrl,Date date);

interface HTMLFetcherResult {

String getHTMLResult();

Date getDate();
}
}

TestHTMLFetcher Class

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.concurrent.Future;

import org.apache.log4j.Logger;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import agonesgr.html.HTMLFetcher;

@Component
public class TestHTMLFetcher implements HTMLFetcher{

@Async(value="htmlFetcherExecutor")
public Future<HTMLFetcher.HTMLFetcherResult> getHTML(String baseUrl, Date date) {
try {
System.out.println("Before execute!!");
Thread.sleep(100000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HTMLFetcher.HTMLFetcherResult r = new TestHTMLFetcher.HTMLFetcherResultImpl("",new Date());

return new AsyncResult<HTMLFetcherResult>(r);
}

private static class HTMLFetcherResultImpl implements HTMLFetcherResult{

private String htmlResult;
private Date date;

public HTMLFetcherResultImpl(String htmlResult, Date date) {
super();
this.htmlResult = htmlResult;
this.date = date;
}

public String getHTMLResult() {
return htmlResult;
}

public Date getDate() {
return date;
}
}
}

And the following excerpt from the context.xml file:


This didn’t work! I submitted 10 tasks to the executor and 10 thread, instead of 1 as I had instructed it had been created. I digged into the Spring code a bit and found the AnnotationAsyncExecutionInterceptor class that was doing tbe job of assigning tasks from methods annotated as async to executors. Putting  a breakpoint on its getExecutorQualifier method it became evident why it doesn’t work.

You need to annotate the interface method rather than the class with the:

@Async(value="htmlFetcherExecutor")

annotation. In my example that is the getHTML method of the HTMLFetcher interface. It now works. I am not sure if it was done on purpose (i.e. if it’s part of the specification). I don’t have time to read the related documentation or search the Spring Jira. However, I would assume that the right place to put the annotation is the implementation. I may want to have two implementations of the same method, one decorated with “Async” that will be asynchronously executed and another without any annotation that will be synchronously executed.

2 thoughts on “Spring Async Method Qualifier to Specify Executor Issue

Leave a reply to Shalom Cancel reply

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

required

Page last modified: 22:39 on June 7, 2015 (UTC+2)