Spring MVC 3.2 Preview: Introducing Servlet 3, Async Support

Engineering
Rossen Stoyanchev
May 07, 2012

Last updated on November 5th, 2012 (Spring MVC 3.2 RC1)

Overview

Spring MVC 3.2 introduces Servlet 3 based asynchronous request processing. This is the first of several blog posts covering this new capability and providing context in which to understand how and why you would use it.

The main purpose of early releases is to seek feedback. We’ve received plenty of it both here and in JIRA since this was first posted after the 3.2 M1 release. Thanks to everyone who gave it a try and commented! There have been numerous changes and there is still time for more feedback!

At a Glance

From a programming model perspective the new capabilities appear deceptively simple. A controller method can now return a java.util.concurrent.Callable to complete processing asynchronously. Spring MVC will then invoke the Callable in a separate thread with the help of a TaskExecutor. Here is a code snippet before:

// Before
@RequestMapping(method=RequestMethod.POST)
public String processUpload(final MultipartFile file) {
// …
return “someView”;
}

// After
@RequestMapping(method=RequestMethod.POST)
public Callable processUpload(final MultipartFile file) {

return new Callable() {
public Object call() throws Exception {
// …
return “someView”;
}
};
}

A controller method can also return a DeferredResult (new type in Spring MVC 3.2) to complete processing in a thread not known to Spring MVC. For example reacting to a JMS or an AMQP message, a Redis notification, and so on. Here is another code snippet:

@RequestMapping("/quotes")
@ResponseBody
public DeferredResult quotes() {
DeferredResult deferredResult = new DeferredResult();
// Add deferredResult to a Queue or a Map…
return deferredResult;
}

// In some other thread…
deferredResult.setResult(data);
// Remove deferredResult from the Queue or Map

The above samples lead to many questions and we’ll get to more details in subsequent posts. For now, I’ll begin by providing some context around these features.

Motivation for Asynchronicity In Web Applications

The most basic motivation for asynchronicity in web applications is to handle requests that take longer to complete. Maybe a slow database query, a call to an external REST APIs, or some other I/O-bound operations. Such longer requests can exhaust the Servlet container thread pool quickly and affect scalability.

In some cases you can return to the client immediately while a background job completes processing. For example sending an email, kicking off a database job, and others represent fire-and-forget scenarios that can be handled with Spring’s @Async support or by posting an event to a Spring Integration channel and then returning a confirmation id the client can use to query for the results.

In other cases, where the result is required, we need to decouple processing from the Servlet container thread or else we’ll exhaust its thread pool. Servlet 3 provides just such support where a Servlet (or a Spring MVC controller) can indicate the response should be left open after the Servlet container thread is exited.

To achieve this, a Servlet 3 web application can call request.startAsync() and use the returned AsyncContext to continue to write to the response from some other separate thread. At the same time from a client’s perspective the request still looks like any other HTTP request-response interaction. It just takes longer to complete. The following is the sequence of events:

Client sends a request
Servlet container allocates a thread and invokes a servlet in it
The servlet calls request.startAsync(), saves the AsyncContext, and returns
The container thread is exited all the way but the response remains open
Some other thread uses the saved AsyncContext to complete the response
Client receives the response 

There is of course a lot more to the Servlet async support. You can find various examples and writeups, but the above sums up the basic, minimum concept you need to know. The next post covers a second motivation for asynchronous request processing – the need for browsers to receive information updates in real time.
comments powered by Disqus

translate:
翻译:

上次更新时间:2012年11月5日(春季MVC 3.2 RC1)
概述
Spring MVC 3.2引入了基于servlet3的异步请求处理。这是几篇博客文章中的第一篇,涵盖了这一新功能,并提供了理解如何以及为什么使用它的上下文。
早期发布的主要目的是寻求反馈。自从这篇文章在3.2版M1发布后第一次发布以来,我们在这里和JIRA都收到了很多。感谢每一个尝试并发表评论的人!已经有无数的变化,还有更多的反馈时间!
一瞥
从编程模型的角度来看,新功能看起来似乎很简单。控制器方法现在可以返回java.util.concurrent.Callable以异步完成处理。然后,Spring MVC将在一个单独的线程中在TaskExecutor的帮助下调用可调用的。下面是之前的代码片段:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值