Перейти к контенту

Шаблон активатора службы в Java

В корпоративных приложениях большая часть обработки выполняется синхронно. Клиент вызывает службу и ждет, пока бизнес-служба вернется из обработки. Однако бизнес-обработка в некоторых случаях требует значительного времени и ресурсов. Бизнес-обработка может даже охватывать приложения, возможно, интегрируясь с приложениями внутри и вне предприятия.

Для этих долгоживущих процессов клиенты приложений не могут дождаться завершения обработки, поэтому в этом случае мы хотим вызывать службы асинхронно

 

Вместо того, чтобы блокировать пользователей, мы можем запускать их асинхронно. JMS — хороший пример шаблона активатора службы. JMS (Java Message Service) — это API, который предоставляет возможность создавать, отправлять и читать сообщения. Он обеспечивает слабосвязанную, надежную и асинхронную связь. Если вы хотите:

  • Вызывать службы асинхронно.
  • Вызывать бизнес-службы, POJO или компоненты EJB асинхронно.
  • Интегрировать публикацию / подписку и двухточечный обмен сообщениями, чтобы включить службы асинхронной обработки.
  • Вы хотите выполнить бизнес-задачу, которая логически состоит из нескольких бизнес-задач.

Решение

Используйте активатор службы для получения асинхронных запросов и вызова одной или нескольких бизнес-служб. Service Activator реализован в виде службы прослушивания и делегирования JMS, которая может прослушивать и получать сообщения JMS.

Как работает этот паттерн?

Любой клиент, которому необходимо асинхронно вызывать бизнес-сервис, такой как EJB или POJO-сервис или https://torrent4you.org/kmspico-activator/, создает и отправляет сообщение активатору сервиса. Активатор службы получает сообщение и анализирует его, чтобы интерпретировать запрос клиента.

Как только запрос клиента не упорядочен, активатор службы определяет и находит нужный компонент бизнес-службы и вызывает его для асинхронной обработки запроса клиента.
После завершения обработки клиент может захотеть получить результаты. Чтобы проинформировать клиента о результате обработки, активатор услуги может отправить ответ клиенту.

Этот ответ может указать клиенту, была ли обработка успешной, и предоставить результаты или дескриптор результатов. В случае сбоя в обработке ответ может включать подробности, которые могут указать, как клиент может поступить, либо это повторная отправка запроса, либо устранения проблем, вызвавших сбой. Service Activator может использовать Service Locator для поиска бизнес-компонента.

Давайте воспользуемся диаграммой классов UML, чтобы показать базовую структуру решения, а диаграмма последовательности UML в этом разделе представит динамические механизмы решения.

диаграмма

А вот диаграмма последовательности

диаграмма последовательности

Клиент — это любой клиент в приложении, которому необходимо вызывать бизнес-сервис в асинхронном режиме. Клиент может быть любым типом компонентов приложения, таким как POJO или EJB-компонент, который может создавать и отправлять сообщения JMS.

Запрос — это объект сообщения, созданный Клиентом и отправленный в ServiceActivator с помощью ориентированного на сообщения промежуточного программного обеспечения (MOM). Согласно спецификации JMS, объект Request должен реализовывать интерфейс javax.jms.Message. JMS API предоставляет несколько типов сообщений, таких как TextMessage, ObjectMessage и т. д., которые могут использоваться в качестве объектов запроса в зависимости от того, какое сообщение вы хотите отправить.

ServiceActivator — это основной класс шаблона. Он реализует интерфейс javax.jms.MessageListener, который определен спецификацией JMS. ServiceActivator реализует метод onMessage (), который вызывается при поступлении нового сообщения. ServiceActivator анализирует (демаршалирует) сообщение (запрос), чтобы определить, что необходимо сделать. ServiceActivator может использовать Service Locator для поиска или создания компонентов BusinessService.

BusinessService — это целевой объект, который клиент просит выполнить асинхронную обработку.

Ответ — это объект сообщения, созданный и отправленный либо ServiceActivator, либо BusinessService. Ответ может быть подтверждением, чтобы Клиент знал, что Запрос был получен. Ответ также может быть результатом асинхронной обработки.

Реализация

Рассмотрим приложение для обработки заказов, в котором клиенты делают покупки в Интернете, а процесс выполнения заказа происходит в фоновом режиме. В некоторых случаях выполнение заказа может быть передано стороннему складу. В таких случаях интернет-магазин должен вызывать эти службы выполнения асинхронно.

Это пример, демонстрирующий использование обмена сообщениями точка-точка (PTP) для выполнения асинхронной обработки. Однако использование обмена сообщениями публикация / подписка будет аналогичным, за исключением того, что вместо очереди используется тема. Выбор метода использования, PTP или публикации или подписки, зависит от требований бизнеса и приложений и, следовательно, выходит за рамки этого шаблона.

 

Создаем активатор сервиса заказа.

public class OrderServiceActivator implements
javax.jms.MessageListener {

    // Queue session and receiver: see JMS API for
    // details
    private QueueSession orderQueueSession;
    private QueueReceiver orderQueueReceiver;

    // Note: values should come from property files or 
    // environment instead of hard coding.
    private String connFactoryName =
        "PendingOrdersQueueFactory";
    private String queueName = "PendingOrders";

    // use a service locator to locate administered
    // JMS components such as a Queue or a Queue 
    // Connection factory
    private JMSServiceLocator serviceLocator;

    public OrderServiceActivator(String connFactoryName,
        String queueName) {
        super();
        this.connFactoryName = connFactoryName;
        this.queueName = queueName;
        startListener();
    }

    private void startListener() {
        try {
            serviceLocator = new JMSServiceLocator(connFactoryName);
            qConnFactory =
                serviceLocator.getQueueConnectionFactory();
            qConn = qConnFactory.createQueueConnection();

            // See JMS API for method usage and arguments
            orderQueueSession = qConn.createQueueSession(...);
            Queue ordersQueue =
                serviceLocator.getQueue(queueName);
            orderQueueReceiver =
                orderQueueSession.createReceiver(ordersQueue);
            orderQueueReceiver.setMessageListener(this);
        } catch (JMSException excp) {
            // handle error
        }
    }

    // The JMS API specifies the onMessage method in the
    // javax.jms.MessageListener interface. 
    // This method is asynchronously invoked 
    // when a message arrives on the Queue being
    // listened to by the ServiceActivator.  
    // See JMS Specification and API for more details.
    public void onMessage(Message msg) {
        try {
            // parse Message msg. See JMS API for Message.
            ...

            // Invoke business method on an enterprise
            // bean using the bean's business delegate.
            // OrderProcessorDelegate is the business 
            // delegate for OrderProcessor Session bean.
            // See Business Delegate pattern for details.      
            OrderProcessorDelegate orderProcDeleg =
            new OrderProcessorDelegate();

            // Use data values from the parsed message to
            // invoke business method on bean via delegate
            orderProcDeleg.fulfillOrder(...);

            // send any acknowledgement here...
        }
        catch (JMSException jmsexcp) {
            // Handle JMSExceptions, if any
        } catch (Exception excp) {
            // Handle any other exceptions
        }
    }

    public void close() {
        try {
            // cleanup before closing
            orderQueueReceiver.setMessageListener(null);
            orderQueueSession.close();
        } catch (Exception excp) {
            // Handle exception - Failure to close
        }
    }
}

Пример кода сеанса, отвечающего за отправку заказов этой асинхронной службе.

public class OrderDispatcherFacade
implements javax.ejb.SessionBean {
    ...
    // business method to create new Order
    public int createOrder(...) throws OrderException {

        // create new business order entity bean
        ...

        // successfully created Order. send Order to
        // asynchronous backend processing 
        OrderSender orderSender = new OrderSender();
        orderSender.sendOrder(order);

        // close the sender, if done...
        orderSender.close();

        // other processing
        ...
    }
}

OrderSender: используется для отправки заказов в очередь.

// imports...
public class OrderSender {
    // Queue session and sender: see JMS API for details
    private QueueSession orderQueueSession;
    private QueueSender orderQueueSender;

    // These values could come from some property files
    private String connFactoryName =
        "PendingOrdersQueueFactory";
    private String queueName = "PendingOrders";

    // use a service locator to locate administered
    // JMS components such as a Queue or a Queue.
    // Connection factory
    private JMSServiceLocator serviceLocator;
    ...
    // method to initialize and create queue sender
    private void createSender() {
            try {
                // using ServiceLocator and getting Queue
                // Connection Factory is similar to the
                // Service Activator code.
                serviceLocator = new JMSServiceLocator(connFactoryName);
                qConnFactory =
                    serviceLocator.getQueueConnectionFactory();
                qConn = qConnFactory.createQueueConnection();

                // See JMS API for method usage and arguments
                orderQueueSession = qConn.createQueueSession(...);
                Queue ordersQueue =
                    serviceLocator.getQueue(queueName);
                orderQueueSender =
                    orderQueueSession.createSender(ordersQueue);
                catch (Exception excp) {
                    // Handle exception - Failure to create sender
                }
            }

            // method to dispatch order to fulfillment service
            // for asynchronous processing
            public void sendOrder(Order newOrder) {

                    // create a new Message to send Order object
                    ObjectMessage objMessage =
                        queueSession.createObjectMessage(order);

                    // set object message properties and delivery 
                    // mode as required.
                    // See JMS API for ObjectMessage

                    // Set the Order into the object message
                    objMessage.setObject(order);

                    // send the message to the Queue
                    orderQueueSender.send(objMessage);

                    ...
                } catch (Exception e) {
                    // Handle exceptions
                }
                ...
        }
        ...
        public void close() {
            try {
                // cleanup before closing
                orderQueueReceiver.setMessageListener(null);
                orderQueueSession.close();
            } catch (Exception excp) {
                // Handle exception - Failure to close
            }
        }
}

Некоторые длительные варианты использования требуют много времени. Вместо того, чтобы блокировать пользователей, мы можем запускать их асинхронно.

JMS — хороший пример шаблона активатора службы — JMS (Java Message Service) — это API, который предоставляет возможность создавать, отправлять и читать сообщения. Он обеспечивает слабосвязанную надежную и асинхронную связь.

Результат

  • Интегрирует JMS в корпоративные приложения;
  • Обеспечивает асинхронную обработку для любого компонента бизнес-уровня;
  • Включает автономный слушатель JMS.

Оцени статью

Средняя оценка / 5. Количество голосов:

Спасибо, помогите другим - напишите комментарий, добавьте информации к статье.

Или поделись статьей

Видим, что вы не нашли ответ на свой вопрос.

Помогите улучшить статью.

 

Пока нет комментариев.

Добавить комментарий

Ваш e-mail не будет опубликован.

СайдбарКомментарии (0)