After reviewing some of the features of Spring 3, i decided to test out the asychronous features via annotation. And below is all the code i needed in order to have a function executed asynchronously in my application:
1: public class Asyncher {
2: @Async
3: public void myMethod(int i) {
4: try {
5: Thread.sleep(2000);
6: } catch (InterruptedException e) {
7: e.printStackTrace();
8: }
9: System.out.println("Running for " + i);
10: }
11:
12: public static void main(String[] args) throws InterruptedException {
13: ApplicationContext ctx = new ClassPathXmlApplicationContext("appContext.xml");
14: Asyncher a = ctx.getBean("asyncher", Asyncher.class);
15: for (int i=0; i<10;i++) {
16: a.myMethod(i);
17: }
18:
19: ThreadPoolTaskExecutor t = ctx.getBean("myExecutor",ThreadPoolTaskExecutor.class);
20: while (t.getActiveCount() > 0) {
21: System.out.println("Number of tasks left: " + t.getActiveCount());
22: Thread.sleep(2000);
23: }
24: t.shutdown();
25: }
26: }
1: <?xml version="1.0" encoding="UTF-8"?>
2: <beans xmlns="http://www.springframework.org/schema/beans"
3: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
4: xmlns:context="http://www.springframework.org/schema/context"
5: xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
6:
7: <task:annotation-driven executor="myExecutor" />
8: <task:executor id="myExecutor" pool-size="2"/>
9: <bean id="asyncher" class="Asyncher"/>
10:
11: </beans>
<task:scheduler id="myScheduler" pool-size="10"/>
You can read about it in the docs here
Important note is that all calls need to be from the highest level so that Spring can intercept. If you invoke one method and then that method invokes the asynchronous annotated one, it will not work. I ran into this problem but solved it by making the code to run asynchronously an inner class. This inner class then needs to be declared in your application context
ReplyDeleteDavid R, you just saved my day man...
ReplyDeleteI was calling @Async methods from within class and wondering why it is still in same thread... :(
Hi David,
ReplyDeletei am facing problem while using the @Async annotation. i am using a file which is been invoked from the web.xml as a contextListener. i am getting error in that file as
Multiple annotations found at this line:
- schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/task/spring-task-3.0.xsd', because 1) could not find the document;
2) the document could not be read; 3) the root element of the document is not .
- cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'task:annotation-driven'.
Can you please help me on this.