Een gids voor berichtgestuurde bonen in EJB

1. Inleiding

Simpel gezegd, een Enterprise JavaBean (EJB) is een JEE-component die op een applicatieserver draait.

In deze tutorial bespreken we Message Driven Beans (MDB), verantwoordelijk voor het verwerken van berichten in een asynchrone context.

MDB's maken deel uit van JEE sinds de EJB 2.0-specificatie; EJB 3.0 introduceerde het gebruik van annotaties, waardoor het gemakkelijker wordt om die objecten te maken. Hier concentreren we ons op annotaties.

2. Wat achtergrondinformatie

Laten we, voordat we ingaan op de details van Message Driven Beans, enkele concepten met betrekking tot berichten bekijken.

2.1. Berichten

Berichten zijn een communicatiemechanisme. Door berichten te gebruiken, kunnen programma's gegevens uitwisselen, zelfs als ze in verschillende programmeertalen zijn geschreven of zich in verschillende operationele systemen bevinden.

Het biedt een losjes gekoppelde oplossing; noch de producent, noch de consument van de informatie hoeven details over elkaar te weten.

Daarom hoeven ze niet eens tegelijkertijd met het berichtensysteem verbonden te zijn (asynchrone communicatie).

2.2. Synchrone en asynchrone communicatie

Tijdens synchrone communicatie wacht de aanvrager tot het antwoord terug is. Ondertussen blijft het aanvragerproces geblokkeerd.

Bij asynchrone communicatie daarentegen, initieert de aanvrager de bewerking maar wordt er niet door geblokkeerd; de aanvrager kan doorgaan met andere taken en het antwoord later ontvangen.

2.3. JMS

Java Message Services ("JMS") is een Java-API die berichtenuitwisseling ondersteunt.

JMS biedt peer-to-peer en publiceer / abonneer berichtmodellen.

3. Bericht gedreven bonen

Een MDB is een component die door de container wordt aangeroepen telkens wanneer een bericht op het berichtensysteem binnenkomt. Als gevolg hiervan activeert deze gebeurtenis de code in deze bean.

We kunnen veel taken uitvoeren binnen een MDB onMessage () methode, aangezien de ontvangen gegevens in een browser worden weergegeven of deze worden geparseerd en in een database worden opgeslagen.

Een ander voorbeeld is het verzenden van gegevens naar een andere wachtrij na enige verwerking. Het komt allemaal neer op onze bedrijfsregels.

3.1. Levenscyclus van Message Driven Beans

Een MDB heeft slechts twee statussen:

  1. Het bestaat niet op de container
  2. gemaakt en klaar om berichten te ontvangen

De afhankelijkheden, indien aanwezig, worden geïnjecteerd direct nadat de MDB is gemaakt.

Om instructies uit te voeren voordat we berichten ontvangen, moeten we een methode annoteren met @ javax.ejb.PostConstruct.

Zowel afhankelijkheidsinjectie als @ javax.ejb.PostConstruct uitvoering gebeurt maar één keer.

Daarna is de MDB klaar om berichten te ontvangen.

3.2. Transactie

Een bericht kan worden afgeleverd bij een MDB binnen een transactiecontext.

Dit betekent dat alle bewerkingen binnen de onMessage () methode maken deel uit van een enkele transactie.

Daarom, als er een terugdraaiing plaatsvindt, levert het berichtensysteem de gegevens opnieuw.

4. Werken met Message Driven Beans

4.1. De consument creëren

Om een ​​Message Driven Bean te creëren, gebruiken we @ javax.ejb.MessageDriven annotatie vóór de klassennaamverklaring.

Om het inkomende bericht af te handelen, moeten we het onMessage () methode van de MessageListener koppel:

@MessageDriven (ActivationConfig = {@ActivationConfigProperty (propertyName = "destination", propertyValue = "tutorialQueue"), @ActivationConfigProperty (propertyName = "destinationType", propertyValue = "javax.jms.Queue")}) public class ReadMessageMDB implementeert void onMessage (Berichtbericht) {TextMessage textMessage = (TextMessage) bericht; probeer {System.out.println ("Bericht ontvangen:" + textMessage.getText ()); } catch (JMSException e) {System.out.println ("Fout bij het consumeren van berichten:" + e.getMessage ()); }}}

Aangezien dit artikel zich richt op annotaties in plaats van .xml-descriptors, zullen we deze gebruiken @ActivatieConfigProperty liever dan .

@ActivatieConfigProperty is een sleutelwaarde-eigenschap die die configuratie vertegenwoordigt. We zullen binnen twee eigendommen gebruiken ActivationConfig, het instellen van de wachtrij en het type object dat de MDB zal verbruiken.

Binnen onMessage () methode waarnaar we de berichtparameter kunnen casten TextMessage, BytesMessage, MapMessage StreamMessage of ObjectMessage.

Voor dit artikel kijken we echter alleen naar de berichtinhoud op standaarduitvoer.

4.2. De producent creëren

Zoals behandeld in paragraaf 2.1, Producenten en consumentendiensten zijn volledig onafhankelijk en kunnen zelfs in verschillende programmeertalen worden geschreven!

We produceren onze berichten met Java-servlets:

@Override beschermde void doGet (HttpServletRequest req, HttpServletResponse res) gooit ServletException, IOException {String text = req.getParameter ("text")! = Null? req.getParameter ("text"): "Hallo wereld"; try (Context ic = nieuwe InitialContext (); ConnectionFactory cf = (ConnectionFactory) ic.lookup ("/ ConnectionFactory"); Wachtrij wachtrij = (Wachtrij) ic.lookup ("wachtrij / tutorialQueue"); Verbindingsverbinding = cf.createConnection ( );) {Session session = connection.createSession (false, Session.AUTO_ACKNOWLEDGE); MessageProducer publisher = session .createProducer (wachtrij); connection.start (); TextMessage-bericht = session.createTextMessage (tekst); publisher.send (bericht); } catch (NamingException | JMSException e) {res.getWriter () .println ("Fout bij verzenden van bericht:" + e.getMessage ()); } res.getWriter () .println ("Bericht verzonden:" + tekst); }

Na het verkrijgen van het ConnectionFactory en Wachtrij instanties, moeten we een Verbinding en Sessie.

Om een ​​sessie aan te maken noemen we de createSession methode.

De eerste parameter in createSession is een boolean die bepaalt of de sessie deel uitmaakt van een transactie of niet.

De tweede parameter wordt alleen gebruikt als de eerste is false. Het stelt ons in staat om de bevestigingsmethode te beschrijven die van toepassing is op inkomende berichten en neemt de waarden van Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE en Sessie.DUPS_OK_ACKNOWLEDGE.

We kunnen nu de verbinding starten, een sms-bericht maken op het sessieobject en ons bericht verzenden.

Een consument die aan dezelfde wachtrij is gebonden, ontvangt een bericht en voert zijn asynchrone taak uit.

Behalve opkijken JNDI objecten, zorgen alle acties in ons try-with-resources-blok ervoor dat de verbinding wordt verbroken als JMSException een fout tegenkomt, zoals een poging om verbinding te maken met een niet-bestaande wachtrij of het opgeven van een verkeerd poortnummer om verbinding te maken.

5. Testen van de Message Driven Bean

Stuur een bericht via de KRIJGEN methode op SendMessageServlet, als in:

//127.0.0.1:8080/producer/SendMessageServlet?text=Text om te verzenden

Ook verzendt de servlet "Hallo Wereld" naar de wachtrij als we geen parameters verzenden, zoals in //127.0.0.1:8080/producer/SendMessageServlet.

6. Conclusie

Met Message Driven Beans kan eenvoudig een op wachtrij gebaseerde applicatie worden gemaakt.

Daarom MDB's stellen ons in staat om onze applicaties te ontkoppelen in kleinere diensten met gelokaliseerde verantwoordelijkheden, waardoor een veel modulair en incrementeler systeem mogelijk is dat kan herstellen van systeemstoringen.

Zoals altijd is de code voorbij op GitHub.