До выхода EJB 3.1 асинхронная обработка могла осуществляться только благодаря JMS и EJB-компонентам, управляемым сообщениями (см. главу 13). Вам приходилось создавать администрируемые объекты (фабрики и пункты назначения JMS), иметь дело с низкоуровневым JMS API для отправки сообщения в пункт назначения, а затем разрабатывать EJB-компонент, управляемый сообщениями, который принял и обработал бы ваше сообщение. JMS сопутствуют хорошие механизмы обеспечения надежности (постоянное хранилище сообщений, гарантии доставки, интеграция с другими системами и т. д.), однако все это может оказаться тяжеловесным при таких сценариях, когда вам требуется просто вызвать метод асинхронно.
С выходом EJB 3.1 у вас появилась возможность вызывать методы асинхронно, просто снабдив метод сессионного EJB-компонента аннотацией @javax.ejb.Asynchronous. В листинге 7.16 приведен OrderEJB, у которого имеется один метод для отправки клиенту сообщений по электронной почте и другой метод для печати заказа. Поскольку выполнение обоих методов занимает много времени, они оба снабжены аннотацией @Asynchronous.
@Stateless
public class OrderEJB {
··@Asynchronous
··public void sendEmailOrderComplete(Order order, Customer customer) {
····// Задача, на решение которой требуется очень много времени
··}
··@Asynchronous
··public void printOrder(Order order) {
····// Задача, на решение которой требуется очень много времени
··}
}
Когда клиент вызывает метод printOrder() либо sendEmailOrderComplete(), контейнер незамедлительно возвращает управление клиенту и продолжает обработку вызова в отдельном потоке выполнения. Как вы можете видеть в листинге 7.16, возвращаемым типом двух асинхронных методов является void. Возможно, это окажется подходящим при подавляющем большинстве сценариев использования, однако иногда возникает необходимость возвратить значение. Асинхронный метод может возвратить void, а также объект java.util.concurrent.Future