简体   繁体   中英

Spring 3.2 @Async task with return type of Future

I am trying to implement a spring @Async task which has a return type of Future, but I can't really figure out how to do it properly.

  1. What will I gain by doing so ? will I now have a controll over my task so I can stop it and run it ?
  2. Is there any reference implementation on how I can do it ? springsource does not provide any.

EDIT

From spring source and spring refrence manual :

Even methods that return a value can be invoked asynchronously. However, such methods are required to have a Future typed return value. This still provides the benefit of asynchronous execution so that the caller can perform other tasks prior to calling get() on that Future.

and the it gives an example like so :

@Async
Future<String> returnSomething(int i) {
// this will be executed asynchronously
}

How to implement this correctly ?

Check out this blog post .

Using @Async allows you to run a computation in a method asynchronously. This means that if it's called (on a Spring managed bean), the control is immediately returned to the caller and the code in the method is run in another thread. The caller receives a Future object that is bound to the running computation and can use it to check if the computation is running and/or wait for the result.

Creating such a method is simple. Annotate it with @Async and wrap the result in AsyncResult , as shown in the blog post.

Check out this blog post .

Important configuration is:

  1. @Async on Spring managed bean method.
  2. Enable async in Spring config XML by defining:
<!-- 
    Enables the detection of @Async and @Scheduled annotations
    on any Spring-managed object.
-->
<task:annotation-driven />

SimpleAsyncTaskExecutor will be used by default.

Wrap the response in a Future<> object.


Example

@Async
public Future<PublishAndReturnDocumentResult> generateDocument(FooBarBean bean) {  
    // do some logic  
    return new AsyncResult<PublishAndReturnDocumentResult>(result);
}

You can then check if the result is done using result.isDone() or wait to get the response result.get() .

The ExecutorService can schedule Callable and return a Future object. The Future is a placeholder that contains result once it's available. It allows you to check if result is there, cancel the task, or block and wait for the results. The Future is useful only when you are expecting some object/value from the task.

Correct way to do the Future call is:

Future<Integer> futureEvenNumber = executorService.submit(new NextEvenNumberFinder(10000));

// Do something.

try {
   Integer nextEvenNumber = futureEvenNumber.get();
} catch (ExecutionException e) {
   System.err.println("NextEvenNumberFinder threw exception: " + e.getCause());
}

The NextEvenNumberFinder class:

public class NextEvenNumberFinder implements Callable<Integer> {
private int number;

public NextEvenNumberFinder(int number) { this.number = number; }

@Override
public Integer call() throws Exception {
    for (;;)
        if (isEvenNumber(++number)) return number;
}

}

Spring Integration Reference Manual: http://static.springsource.org/spring-integration/reference/htmlsingle/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM