Mock tests, Interview questions, Tutorials and Tech news
 
 
Home > Programming / tutorials > Asynchronous method invocation in Spring 3.0

Asynchronous method invocation in Spring 3.0

January 13th, 2010 Leave a comment Go to comments

Spring 3.0  has added  annotation support for both task scheduling and asynchronous method execution.  We will discuss @Async annotation and its uses.

The @Async annotation

The @Async annotation allows invocation of that method to occur asynchronously. In other words, the caller will return immediately upon invocation.

One of the use cases of @Async function can be in situations where in user registers and system has to send confirmation mail or any similar task where you do not want to block user.

We will look at the  example below to explain it more clearly . Since for most of you this will be first Spring 3.0 application, please notice the changes in applicationContext.xml.

<?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:p=”http://www.springframework.org/schema/p” xmlns:context=”http://www.springframework.org/schema/context”
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-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd”>

<context:component-scan base-package=”cs”/>

</beans>

Let us now look at our classes

TestService.java

import org.springframework.context.support.ClassPathXmlApplicationContext;
import cs.service.RegularService;

public class TestService {

public static void main(String args[]){

ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {
“applicationContext.xml”});

RegularService regService = (RegularService) appContext.getBean(“regularService”);

regService.registerUser(“Skill-Guru”);

}

}

RegularService.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cs.async.MailUtility;

@Service
public class RegularService {

@Autowired
private MailUtility mailUtility ;

public void registerUser(String userName){

System.out.println(” User registration for  “+userName +” complete”);

mailUtility.sendMail(userName);

System.out.println(” Registration Complete. Mail will be send after 5 seconds “);
}

}

MailUtility.java

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class MailUtility {

@Async
public void sendMail(String name){

System.out.println(” I Will be formatting html mail and sending it  “);

try {
Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();
}

System.out.println(” Asynchronous method call of send email — Complete “);

}

}

Once you run the TestService.java the output would be

User registration for  Skill-Guru complete
I Will be formatting html mail and sending it
Asynchronous method call of send email — Complete
Registration Complete. Mail will be send after 5 seconds

Now wait a minute. This does not look like asynchronous call. What the hell is wrong here ?

We missed <task:annotation-driven/> in applicationContext.xml

The modified applicationContext.xml would be

<?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:p=”http://www.springframework.org/schema/p” 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-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd“>

<context:component-scan base-package=”cs”/>

<task:annotation-driven/>

</beans>

Notice the changes in bold.

Now run your TestService again. The output would be

User registration for  Skill-Guru complete
Registration Complete. Mail will be send after 5 seconds
I Will be formatting html mail and sending it

The program will not exit and after 5 second you will see

Asynchronous method call of send email — Complete

You can see registerUser calls sendMail and the control is returned back to caller immediately.

Are you preparing for Spring Certification ? Try out the Spring certification Mock Practice test

Be Sociable, Share!
  1. miro
    March 25th, 2013 at 17:57 | #1

    i did the example exactly as described but the call does not seem to be Async it waits untill the sendMail finishes. i tried with wait(15000) it waits 15 seconds then it goes back to continue.
    it seems that @Async does not work :(

    please help

  2. AD
    March 11th, 2013 at 09:48 | #2

    Hi,Is the Thread.sleep(5000) required for it to function asynchronously.?

  3. Richard
    March 7th, 2013 at 09:42 | #3

    Simple and excellent. Thank you!

  4. s_a
    January 8th, 2013 at 07:01 | #4

    async call stop processing(method which was called Asynchronously) as soon as the request is returned from the controller .
    can you explain this scenario?

  5. raj
    January 6th, 2013 at 12:53 | #5

    how do we in implement in the Jee application ?

  6. raj
    January 4th, 2013 at 16:15 | #6

    This does not work.

  7. Rahul
    December 13th, 2012 at 12:27 | #7

    Thanks man ! made my day :)

  8. Amod
    November 28th, 2012 at 06:24 | #8

    That one line saved my day. Thanks a lot for the good article

  9. sajid
    May 23rd, 2012 at 00:54 | #9

    hello,
    thanks a lot for this nice introduction. but there’s a single line of code missing in the applicationContext.xml file

    xmlns:task=”http://www.springframework.org/schema/task” in .

    without this line, you’re very much likely to get this error “The prefix “task” for element “task:annotation-driven” is not bound.” error.

    happy coding :)

  10. macrotea
    September 29th, 2011 at 22:04 | #10

    hi
    i am a chinese spring developer
    thx for your introduction

  11. Marc
    January 29th, 2011 at 09:06 | #11

    When used in combination with Hibernate, I run into org.hibernate.LazyInitializationException s
    What’s the best way to create an open session in view for the Async method?

  12. qbe
    October 30th, 2010 at 06:19 | #12

    @stats

    You can use an http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html as return value of an Async annotated method.

  13. October 5th, 2010 at 10:06 | #13

    @stas When you say outcome , what do you exactly mean ?
    The aysnc method will do job in background and exit. You can log the message when the method completes its execution.

  14. stas
    October 5th, 2010 at 04:24 | #14

    Is there a way to get an outcome of the ansync method?

  15. August 4th, 2010 at 23:06 | #15

    @Paramesh
    Thanks for pointing out Paramesh. It should be Thread.sleep(5000).
    I fixed it.

  16. Paramesh
    August 4th, 2010 at 22:18 | #16

    Hello ,

    Its really good, I would like know about where did you specify the 5 seconds in above.. I notice that below one in above program ..
    The program will not exit and after 5 second you will see .. but i noticed that in Thread.sleep(10000)..

    Please advice

  17. August 4th, 2010 at 06:56 | #17

    Excellent point Michael. Thanks a lot fro bringing this up.

  18. Michael
    August 4th, 2010 at 04:13 | #18

    Thanks for that post!

    A small hint if you using async and annotation-based transactionhandling. You will need the async call before the method or facade with the @transactional otherwise the transactioncontext will not be expanded to the new thread….

    greetings michael

  19. Genie
    June 10th, 2010 at 10:04 | #19

    thanks! short and sweet!

  20. Jijik
    February 17th, 2010 at 04:18 | #20

    Sorry, the problem was caused by implementing an TestService as junit test in my case and the junit test finished before background threads write anything to stdout.

    Many thanks for great example!

  21. Jijik
    February 17th, 2010 at 03:16 | #21

    Hello, I have tried the example above and unfortunately it does not works :(

    When I run the TestService it prints only:
    User registration for Skill-Guru complete
    Registration Complete. Mail will be send after 5 seconds
    But MailUtility.sendMail method is not invoked.

    When I removed the @Async annotation I got all four messages:
    User registration for Skill-Guru complete
    I Will be formatting html mail and sending it
    Asynchronous method call of send email — Complete
    Registration Complete. Mail will be send after 5 seconds

    Any idea whats wrong? Why the sendMail method is not invoked?

    Many thanks for any help!

  22. January 18th, 2010 at 21:56 | #22

    Thanks mKyong for mentioning the post. I appreciate it.

  23. Dai bang Canh cut
    January 17th, 2010 at 21:42 | #23

    Thank you for your introduction. It’s really helpful.

  24. January 15th, 2010 at 16:03 | #24

    oh, i like new info about Asynchronous. Thanks guys!

  1. January 15th, 2010 at 21:01 | #1
  2. January 17th, 2010 at 02:31 | #2
  3. January 18th, 2010 at 05:37 | #3
  4. January 18th, 2010 at 21:38 | #4
  5. June 29th, 2011 at 21:05 | #5
  6. October 21st, 2012 at 16:20 | #6

Get Adobe Flash playerPlugin by wpburn.com wordpress themes