Ръководство за боб, управляван от съобщения в EJB

1. Въведение

Просто казано, Enterprise JavaBean (EJB) е JEE компонент, който работи на сървър на приложения.

В този урок ще обсъдим управлявани от съобщения зърна (MDB), отговорни за обработката на съобщенията в асинхронен контекст.

MDB са част от JEE от спецификацията EJB 2.0; EJB 3.0 въведе използването на анотации , улеснявайки създаването на тези обекти. Тук ще се съсредоточим върху анотациите.

2. Някои предистория

Преди да се впуснем в подробностите, управлявани от съобщения, нека прегледаме някои концепции, свързани със съобщенията.

2.1. Съобщения

Съобщенията са комуникационен механизъм. Използвайки съобщения, програмите могат да обменят данни, дори ако са написани на различни програмни езици или се намират в различни операционни системи.

Предлага свободно свързано решение; нито производителят, нито потребителят на информацията трябва да знаят подробности един за друг .

Следователно те дори не трябва да бъдат свързани към системата за съобщения едновременно (асинхронна комуникация).

2.2. Синхронна и асинхронна комуникация

По време на синхронна комуникация заявителят изчаква, докато отговорът се върне. Междувременно процесът на заявителя остава блокиран.

В асинхронната комуникация, от друга страна, заявителят инициира операцията, но не е блокиран от нея; заявителят може да премине към други задачи и да получи отговора по-късно.

2.3. JMS

Java Message Services (“JMS”) е Java API, който поддържа съобщения.

JMS предоставя равнопоставени и публикува / абонира модели за съобщения.

3. Фасул, управляван от съобщения

MDB е компонент, извикан от контейнера всеки път, когато в системата за съобщения пристигне съобщение. В резултат това събитие задейства кода вътре в този боб.

Можем да изпълняваме много задачи в метода MDB onMessage () , тъй като показваме получените данни в браузър или анализираме и запазваме в база данни.

Друг пример е изпращането на данни на друга опашка след известна обработка. Всичко се свежда до нашите бизнес правила.

3.1. Жизнен цикъл, управляван от съобщения

MDB има само две състояния:

  1. Не съществува в контейнера
  2. създадени и готови за получаване на съобщения

Зависимостите, ако има такива, се инжектират веднага след създаването на MDB.

За да изпълним инструкции преди да получаваме съобщения, трябва да анотираме метод с @ javax.ejb. PostConstruct .

И двете инжектиране на зависимост и @ javax.ejb. Изпълнението на PostConstruct се случва само веднъж.

След това MDB е готов за получаване на съобщения.

3.2. Транзакция

Съобщение може да бъде доставено до MDB в контекста на транзакцията.

Означава, че всички операции в метода onMessage () са част от една транзакция.

Следователно, ако се случи връщане назад, системата за съобщения предоставя повторно данните.

4. Работа с боб, задвижван от съобщения

4.1. Създаване на потребител

За да създадем Bean, управляван от съобщения, използваме анотация @ javax.ejb.MessageDriven преди декларацията за името на класа.

За да обработим входящото съобщение, трябва да внедрим метода onMessage () на интерфейса MessageListener :

@MessageDriven(activationConfig = { @ActivationConfigProperty( propertyName = "destination", propertyValue = "tutorialQueue"), @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class ReadMessageMDB implements MessageListener { public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { System.out.println("Message received: " + textMessage.getText()); } catch (JMSException e) { System.out.println( "Error while trying to consume messages: " + e.getMessage()); } } }

От тази статия се фокусира върху анотации вместо .xml описания ще използваме @ActivationConfigProperty вместо .

@ActivationConfigProperty е свойство ключ-стойност, което представлява тази конфигурация. Ще използваме две свойства в activationConfig , като зададем опашката и вида на обекта, който MDB ще консумира.

Вътре в метода onMessage () можем да предадем параметъра на съобщението към TextMessage, BytesMessage, MapMessage StreamMessage или ObjectMessage .

За тази статия обаче ще разгледаме само съдържанието на съобщението на стандартния изход.

4.2. Създаване на продуцент

Както е описано в раздел 2.1, услугите за производители и потребители са напълно независими и дори могат да бъдат написани на различни програмни езици !

Ние ще произвеждаме нашите съобщения с помощта на Java сървлети:

@Override protected void doGet( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String text = req.getParameter("text") != null ? req.getParameter("text") : "Hello World"; try ( Context ic = new InitialContext(); ConnectionFactory cf = (ConnectionFactory) ic.lookup("/ConnectionFactory"); Queue queue = (Queue) ic.lookup("queue/tutorialQueue"); Connection connection = cf.createConnection(); ) { Session session = connection.createSession( false, Session.AUTO_ACKNOWLEDGE); MessageProducer publisher = session .createProducer(queue); connection.start(); TextMessage message = session.createTextMessage(text); publisher.send(message); } catch (NamingException | JMSException e) { res.getWriter() .println("Error while trying to send  message: " + e.getMessage()); } res.getWriter() .println("Message sent: " + text); }

След като получим екземплярите ConnectionFactory и Queue , трябва да създадем Connection and Session .

За да създадем сесия, ние извикваме метода createSession .

The first parameter in createSession is a boolean which defines whether the session is part of a transaction or not.

The second parameter is only used when the first is false. It allows us to describe the acknowledgment method that applies to incoming messages and takes the values of Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE and Session.DUPS_OK_ACKNOWLEDGE.

We can now start the connection, create a text message on the session object and send our message.

A consumer, bound to the same queue will receive a message and perform its asynchronous task.

Also, apart from looking up JNDI objects, all actions in our try-with-resources block make sure the connection is closed if JMSException encounters an error, such as trying to connect to a non-existing queue or specifying a wrong port number to connect.

5. Testing the Message Driven Bean

Send a message through the GET method on SendMessageServlet, as in:

//127.0.0.1:8080/producer/SendMessageServlet?text=Text to send

Also, the servlet sends “Hello World” to the queue if we don't send any parameters, as in //127.0.0.1:8080/producer/SendMessageServlet.

6. Conclusion

Message Driven Beans allow simple creation of a queue based application.

Следователно MDB ни позволяват да разделим нашите приложения на по-малки услуги с локализирани отговорности , позволявайки много по-модулна и постепенна система, която може да се възстанови от системни откази.

Както винаги кодът приключи на GitHub.