Spring MVC的@ Async,DeferredResult和Callable之间的区别 [英] Difference between Spring MVC's @Async, DeferredResult and Callable

查看:636
本文介绍了Spring MVC的@ Async,DeferredResult和Callable之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Spring服务中定义了一个长期运行的任务.它由Spring MVC控制器启动.我想启动服务,并在服务结束之前将HttpResponse返回给调用方.该服务最后将文件保存在文件系统上. 在javascript中,我创建了一个轮询作业以检查服务状态.

I've a long-running task defined in a Spring service. It is started by a Spring MVC controller. I want to start the service and return back an HttpResponse to the caller before the service ends. The service saves a file on file system at end. In javascript I've created a polling job to check service status.

在Spring 3.2中,我找到了@Async批注,但是我不明白它与DeferredResultCallable有何不同.我什么时候必须使用@Async,什么时候应该使用DeferredResult?

In Spring 3.2 I've found the @Async annotation, but I don't understand how it is different from DeferredResult and Callable. When do I have to use @Async and when should I use DeferredResult?

推荐答案

异步注释了一个方法,因此它将被异步调用.

Async annotates a method so it is going to be called asynchronously.

@org.springframework.stereotype.Service
public class MyService {
    @org.springframework.scheduling.annotation.Async
    void DoSomeWork(String url) {
        [...]
    }
}

因此Spring可以这样做,因此您需要定义如何执行.例如:

So Spring could do so you need to define how is going to be executed. For example:

<task:annotation-driven />
<task:executor id="executor" pool-size="5-10" queue-capacity="100"/>

这样,当您调用service.DoSomeWork("parameter")时,调用将被放入执行程序的队列中以被异步调用.这对于可以同时执行的任务很有用.

This way when you call service.DoSomeWork("parameter") the call is put into the queue of the executor to be called asynchronously. This is useful for tasks that could be executed concurrently.

您可以使用Async执行任何类型的异步任务.如果您要定期调用任务,则可以使用 @Scheduled (并使用task:scheduler而不是task:executor).它们是调用Java Runnable的简化方法.

You could use Async to execute any kind of asynchronous task. If what you want is calling a task periodically you could use @Scheduled (and use task:scheduler instead of task:executor). They are simplified ways of calling java Runnables.

DeferredResult<> 用于回答请愿书,而不会阻止用于回答的Tomcat HTTP线程.通常,它将作为ResponseBody注释方法的返回值.

DeferredResult<> is used to answer to a petition without blocking the Tomcat HTTP thread used to answer. Usually is going to be the return value for a ResponseBody annotated method.

@org.springframework.stereotype.Controller
{
    private final java.util.concurrent.LinkedBlockingQueue<DeferredResult<String>> suspendedRequests = new java.util.concurrent.LinkedBlockingQueue<>();

    @RequestMapping(value = "/getValue")
    @ResponseBody
    DeferredResult<String> getValue() {
            final DeferredResult<String> result = new DeferredResult<>(null, null);
            this.suspendedRequests.add(result);
            result.onCompletion(new Runnable() {
            @Override
            public void run() {
        suspendedRequests.remove(result);
            }
});
            service.setValue(result); // Sets the value!
            return result;
    }
}

前面的示例缺少一件事,它没有显示如何设置递归结果.在其他方法(可能是setValue方法)中,将有一个result.setResult(value).在调用setResult之后,Spring将调用onCompletion过程并返回对HTTP请求的答案(请参见 https://en.wikipedia.org/wiki/Push_technology#Long_polling ).

The previous example lacks one important thing and it's that doesn't show how the deferred result is going to be set. In some other method (probably the setValue method) there is going to be a result.setResult(value). After the call to setResult Spring is going to call the onCompletion procedure and return the answer to the HTTP request (see https://en.wikipedia.org/wiki/Push_technology#Long_polling).

但是,如果您只是同步执行setValue,则使用延迟结果没有任何优势,这就是Async的用武之地.您可以使用异步方法在将来的某个时间使用另一个线程来设置返回值.

But if you just are executing the setValue synchronously there is no advantage in using a deferred result.Here is where Async comes in hand. You could use an async method to set the return value in some point in the future using another thread.

    @org.springframework.scheduling.annotation.Async
    void SetValue(DeferredResult<String> result) {
        String value;
        // Do some time consuming actions
        [...]
        result.setResult(value);
    }

使用延迟的结果并不需要异步,这只是做到这一点的一种方法.

Async is not needed to use a deferred result, its just one way of doing it.

在该示例中,有一系列延迟的结果,例如,计划的任务可能正在监视以处理其未决请求.另外,您可以使用一些非阻塞机制(请参见 http://en.wikipedia.org/wiki/New_I/O )来设置返回值.

In the example there is a queue of deferred results that, for example, a scheduled task could be monitoring to process it's pending requests. Also you could use some non blocking mechanism (see http://en.wikipedia.org/wiki/New_I/O) to set the returning value.

要完成此操作,您可以搜索有关Java标准期货的信息(

To complete the picture you could search information about java standard futures (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html) and callables (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html) that are somewhat equivalent to Spring DeferredResult and Async.

这篇关于Spring MVC的@ Async,DeferredResult和Callable之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆