Working with asynchronous tasks

Java 7 has a feature called Future. Futures let you retrieve the result of an asynchronous operation at a later time. The FutureTask class runs in a separate thread, which allows you to perform non-blocking asynchronous operations. Spring provides an @Async annotation to make it more easier to use. We'll explore Java's Future feature and Spring's @Async declarative approach:

  1. Create a project, TimeTravellingWithSpring, and add a package, com.packt.async.
  2. We'll exercise a bank's use case, where an automated job will run and settle loan accounts. It will also find all the defaulters who haven't paid the loan EMI for a month and then send an SMS to their number. The job takes time to process thousands of accounts, so it will be good if we can send SMSes asynchronously to minimize the burden of the job. We'll create a service class to represent the job, as shown in the following code snippet:
    @Service
    public class AccountJob {
       @Autowired
       private SMSTask smsTask;
    
       public void process() throws InterruptedException, 
              ExecutionException {
      System.out.println("Going to find defaulters... ");
    
      Future<Boolean> asyncResult =smsTask.send("1", "2", "3");
      System.out.println("Defaulter Job Complete. SMS will be 
               sent to all defaulter");
        
      Boolean result = asyncResult.get();
      System.out.println("Was SMS sent? " + result);
      }
    }

    The job class autowires an SMSTask class and invokes the send method with phone numbers. The send method is executed asynchronously and Future is returned. When the job calls the get() method on Future, a result is returned. If the result is not processed before the get() method invocation, the ExecutionException is thrown. We can use a timeout version of the get() method.

  3. Create the SMSTask class in the com.packt.async package with the following details:
    @Component
    public class SMSTask {
    
      @Async
      public Future<Boolean>  send(String... numbers) {
      System.out.println("Selecting SMS format  ");
    
      try {
        Thread.sleep(2000);
      } catch (InterruptedException e) {
          e.printStackTrace();
          return new AsyncResult<>(false);
      }
      System.out.println("Async SMS send task is Complete!!!");
      return new AsyncResult<>(true);
      }
    }

    Note that the method returns Future, and the method is annotated with @Async to signify asynchronous processing.

  4. Create a JUnit test to verify asynchronous processing:
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations="classpath:com/packt/async/
              applicationContext.xml")
    public class AsyncTaskExecutionTest {
    
      @Autowired ApplicationContext context;
      
      @Test
      public void jobTest() throws Exception {
        AccountJob job = 
              (AccountJob)context.getBean(AccountJob.class);
        job.process();
      }
    }

    The job bean is retrieved from the applicationContext file and then the process method is called. When we execute the test, the following output is displayed:

    Going to find defaulters... 
    Defaulter Job Complete. SMS will be sent to all defaulter
    Selecting SMS format  
    Async SMS send task is Complete!!!
    Was SMS sent? true

    During execution, you might feel that the async task is executed after a delay of 2 seconds as the SMSTask class waits for 2 seconds.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.18.101