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:
TimeTravellingWithSpring
, and add a package, com.packt.async
.@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.
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.
@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.
3.145.18.101