Simple Asynchronous Processing with Spring’s TaskExecutor
Posted by Helena Edelson on 27th January 2010
This post is merely meant as a starting guide to tinkering for a light-weight solution to handing off execution of a task for async processing without the overhead of Spring Batch or Spring JMS and Message Brokers, among other middleware solutions.
1. I have a simplistic junit test that merely kicks off the service method to view the path of execution:
/**
* TaskTests
*
* @author Helena Edelson
* @since v 1.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:infrastructure-context.xml"})
public class TaskTests extends BaseTest {
protected static final Logger logger = Logger.getLogger(TaskTests.class);
@Autowired private OrderService orderService;
@Test
public void testExecution(){
logger.debug("Starting execution thread...");
orderService.dispatch(new Order());
}
}
2. A simple context config:
<?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”
xmlns:aop=”http://www.springframework.org/schema/aop”
xmlns:p=”http://www.springframework.org/schema/p”
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-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”>
<bean id=”taskExecutor” class=”org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor” p:corePoolSize=”5″ p:maxPoolSize=”25″/>
<!– OR alternately: Creates a org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor –>
<task:executor id=”taskExecutor” pool-size=”5-25″ queue-capacity=”100″ rejection-policy=”CALLER_RUNS”/>
</beans>
3. OrderService that delegates to the ThreadPoolTaskExecutor:
/**
* OrderServiceImpl is used for both orders and returns
*
* @author Helena Edelson
* @MessageEndpoint which is a @Component
* @since Dec 29, 2009
*/
@Service("orderService")
public class OrderServiceImpl implements OrderService {
private OrderDao orderDao;
private MerchantService merchantService;
private ReceivingService receivingService;
@Autowired private TaskExecutor taskExecutor;
@Autowired
public OrderServiceImpl(OrderDao orderDao, ReceivingService receivingService, MerchantService merchantService) {
this.orderDao = orderDao;
this.receivingService = receivingService;
this.merchantService = merchantService;
}
public final void dispatch(final Order order) {
logger.debug("Starting dispatch execution...");
if (this.taskExecutor != null) {
this.taskExecutor.execute(new Runnable() {
public void run() {
executorAsync(order);
}
});
}
logger.debug("Completed dispatch execution...");
}
private final void executorAsync(final Order order) {
logger.debug("Starting Async execution...");
daoDatasourceOne.createOrder(order);
daoDatasourceTwo.createOrder(order);
logger.debug("Completed Async execution...");
}
/* Where the output will be: Note the dispatch method returns control to its caller before the async method begins:
2010-01-27 13:23:27,546 [main] DEBUG org.springsource.oms.infrastructure.TaskTests - Starting execution thread...
2010-01-27 13:23:27,546 [main] DEBUG org.springsource.oms.domain.services.OrderServiceImpl - Starting dispatch execution...
2010-01-27 13:23:27,546 [main] DEBUG org.springsource.oms.domain.services.OrderServiceImpl - Completed dispatch execution...
2010-01-27 13:23:27,546 [taskExecutor-1] DEBUG org.springsource.oms.domain.services.OrderServiceImpl - Starting Async execution...
persisting org.springsource.oms.domain.entities.Order@1f10a67
*/
/**
* Alternately for a different scenario you can play around with this:
*/
public void withExecutor(final Order order) {
try {
CompletionService
I recommend looking into the @Async annotation, which I will post on shortly. In the meantime here is the ref page for Spring Task and Scheduling: http://static.springsource.org/spring/docs/3.0.x/reference/html/scheduling.html
Posted in Annotations, Concurrency, Java, Spring, Spring Task | No Comments »
