In Spring, an allocated amount of memory is allocated for request processing. If you are running a long operation (such as uploading a large file, batch mailing, big data analysis), the memory for that request would be blocked until the operation is finished.
A better way of approaching this would be to return the request right away and let the long operation to run in another thread.
In Spring 3.x, it is relatively easy with the @Async support.
Before I dive down into the tutorial, here's my specs:
- ubuntu 12.04
- large EC2 instance
- OpenJDK 1.7
- Maven 3.0.4
- Spring 3.2.4
- CXFServlet 2.5.3 with JAX-RS (This is for Rest API)
This post will be about how to enable @Async in your spring project.
Install the latest version of Spring
At the time of this writing, the stable version is 3.2.4. The following shows how to add the maven dependency in pom.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dependencies> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-context</artifactId> | |
<version>3.2.4.RELEASE</version> | |
</dependency> | |
</dependencies> |
Use Serlvet 3.0 namespace
In web.xml, make sure you use the XML nameplace for version 3.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<web-app xmlns="http://java.sun.com/xml/ns/javaee" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" | |
version="3.0"> | |
</web-app> |
Add Async Support in entry servlets in web.xml
If you are writing a normal Spring MVC Web app, you will need to add async-supported in the dispatcher serlvet below. My project only uses the Rest API, so I put the async-supported xml tag in the CXFServlet.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<servlet> | |
<servlet-name>dispatcher</servlet-name> | |
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> | |
<load-on-startup>1</load-on-startup> | |
</servlet> | |
<servlet> | |
<servlet-name>CXFServlet</servlet-name> | |
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> | |
<async-supported>true</async-supported> | |
</servlet> |
Enable Async in application context
In applicationContext.xml, enable executor and scheduler. If you don't know where is the applicationContext.xml, find it from web.xml's contextConfigLocation context-param field.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:context="http://www.springframework.org/schema/context" | |
xmlns:task="http://www.springframework.org/schema/task" | |
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd | |
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd | |
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd" | |
default-lazy-init="true"> | |
<!-- async support --> | |
<task:annotation-driven executor="myExecutorService" scheduler="mySchedulerService" /> | |
<task:executor id="myExecutorService" pool-size="5-10" queue-capacity="10" /> | |
<task:scheduler id="mySchedulerService" pool-size="10" /> | |
</beans> |
Make sure you have the task namespace as above.
Annotate a method as @Async
Below is a quick test of the @Async method. Notice the @Async annotation below.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface MyService { | |
Future<String> testAsync(); | |
} | |
@Service | |
@Transactional | |
public class MyServiceImpl implements MyService { | |
@Async | |
@Override | |
public Future<String> testAsync() { | |
String hello = "world"; | |
String threadName = Thread.currentThread().getName(); | |
System.out.println(" " + threadName + " beginning work"); | |
try { | |
Thread.sleep(10000); // simulates work | |
} | |
catch (InterruptedException e) { | |
Thread.currentThread().interrupt(); | |
} | |
System.out.println(" " + threadName + " completed work"); | |
return new AsyncResult<String>(hello); | |
} | |
} | |
public interface MyApiService { | |
String testAsync() throws Exception; | |
} | |
@Path("/api") | |
@Service("srvMyApi") | |
public class MyApiServiceImpt implements MyApiService { | |
@Override | |
@GET | |
@Path("/testAsync") | |
@Produces(MediaType.APPLICATION_JSON) | |
public String testAsync() throws Exception { | |
Future<String> future = bookService.testAsync(); | |
HttpServletRequest req = context.getHttpServletRequest(); | |
return "called Async"; | |
} | |
} |
Try taking out the @Async annotation and execute the program. You should be able to observe the difference.
Interesting topic for a blog. I have been searching the Internet for fun and came upon your website. Fabulous post. Thanks a ton for sharing your knowledge! It is great to see that some people still put in an effort into managing their websites. I'll be sure to check back again real soon.
ReplyDeleteMinecraft Server List
Intresting information app spring java i love iot and wants to get more info about it
ReplyDelete