Ejb3.0 EJB message-driven bean Development

Source: Internet
Author: User
Tags jboss server

(7) ejb3.0 EJB message-driven bean JMS Development

  I. Java Message Service)

  

  Ii. Messages in JMS

The center of the message passing system is the message. A Message consists of three parts:
Header, property, and body ).

Messages are of the following types, all of which are derived from the message interface.
Streammessage: a message that contains a Java primitive Value Stream. The filling and reading operations are performed in order.
Mapmessage: a message that contains a group of name-value pairs. The order of entries is not defined.
Textmessage: a message that contains a Java string (for example, an XML message ).
Objectmessage: a message that contains serialized Java objects.
Bytesmessage: a message that contains continuous byte streams.


Message transmission model
JMS supports two message transmission models: point-to-point (PTP) and publish/subscribe (pub/Sub ). The two message passing models are very similar, but there are the following differences:

The PTP message transmission model specifies that a message can only be transmitted to one receiver. It is represented by javax. JMS. queue.
The pub/sub message passing model allows one message to be transmitted to multiple receivers. Represented by javax. JMS. Topic

Both models are implemented by extending the public base class. For example, javax. JMS. queue and javax. JMS. Topic are both extended from the javax. JMS. Destination class.

  Point-to-Point model:

  

  Publishing or subscription mode:

  

  3. Configure the target address

  Before starting JMS programming, We need to configure the destination address (destination) for the message to arrive, because only the destination address exists, we can send the message to this address. As each application server has different configuration methods for the target address, the following uses JBoss as an example to configure a target address of the queue type.

  

  The configuration address used in this article: publish this file in JBoss.

<XML version = "1.0" encoding = "UTF-8"> <Server> <mbean code = "org. JBoss. MQ. server. JMX. queue "name =" JBoss. MQ. destination: service = queue, name = itmqueue "> <attribute name =" jndiname "> queue/itmqueue </attribute> <depends optional-Attribute-name =" destinationmanager "> JBoss. MQ: service = destinationmanager </depends> </mbean> <mbean code = "org. JBoss. MQ. server. JMX. topic "name =" JBoss. MQ. destination: service = topic, name = itmtopic "> <attribute name =" jndiname "> topic/itmtopic </attribute> <depends optional-Attribute-name =" destinationmanager "> JBoss. MQ: service = destinationmanager </depends> </mbean> </Server>
Before the target address itmqueue is published, you must first publish the manager destinationmanager of the target address. Therefore, depends is used to declare the dependency.

The publishing process is the same as that of data source and EJB. Just copy it to the JBoss server/default/deploy directory. After the copy, you can view the information on the JBoss console:
[Itcastqueue] bound to JNDI name: queue/itmqueue

  It indicates that the destination address itcastqueue is bound to the queue name/itcastqueue.
The supervisor name of queue/itcastqueue is not in front of Java:, that is, this name is in the global namespace and can be accessed by external applications.
After the release, you can go to the JBoss management background and find JBoss. MQ. in the destination column, find the target address name = itcastqueue. service = queue. Click it to view some information.

4. After the target address is set up, the message can be sent.

To send a message in a Java class, follow these steps:

  (1) Get a JNDI initialization context (context)
Initialcontext CTX = new initialcontext ();
(2) query a connection factory named queueconnectionfactory Based on the context. The connection factory is provided by JMS and does not need to be created by ourselves. Each Vendor binds a global JNDI for it and we can obtain it through its Global JNDI;
Queueconnectionfactory factory = (queueconnectionfactory) CTX. Lookup ("queueconnectionfactory ");
(3) Get a connection queueconnection from the connection Factory
Conn = factory. createqueueconnection ();
(4) Establish a session through a connection );
Session = conn. createqueuesession (false, queuesession. auto_acknowledge );
This code indicates creating a session that does not require transactions and can automatically confirm that the message has been received.
(5) Find the target address:
Sample Code: Destination = (destination) CTX. Lookup ("queue/foshanshop ");
(6) Create messageproducer (both queuesender and topicpublisher are extended from the messageproducer Interface) based on the session and target address)

  
Sample Code:

Messageproducer producer = session. createproducer (destination); textmessage MSG = session. createtextmessage ("Hello, this is my first message-driven Bean"); producer. Send (MSG );

  Method 1:

Package CN. ITM. APP; import javax. JMS. destination; import javax. JMS. messageproducer; import javax. JMS. queueconnection; import javax. JMS. queueconnectionfactory; import javax. JMS. queuesession; import javax. JMS. textmessage; import javax. naming. initialcontext; public class queuesender {public static void main (string [] ARGs) {try {initialcontext CTX = new initialcontext (); // query the connection factory of the queue type. Queueconnectionfactory factory = (queueconnectionfactory) CTX. lookup ("queueconnectionfactory"); queueconnection conn = factory. createqueueconnection (); // creates a session to this address. The second parameter is the message confirmation mode. The automatic confirmation mode is used here. Queuesession session = conn. createqueuesession (false, queuesession. auto_acknowledge); // connection name of the target address. Destination = (destination) CTX. Lookup ("queue/itmqueue"); // create a message sender. Messageproducer producer = session. createproducer (destination); textmessage MSG = session. createtextmessage ("Hello, this is my first message-driven Bean"); producer. send (MSG); // system. out. println (MSG); Session. close (); Conn. close ();} catch (exception e) {e. printstacktrace ();}}}

  Run queuesender to send a message to the target address.
After the message is sent, you can write the receiver of the message.

Message-driven bean is used to receive messages.

  Message-driven Bean (MDB) is a component designed specifically to process message requests. Like stateless Session Bean, it also uses the instance pool technology. containers can use a certain number of bean instances to concurrently process hundreds of JMS messages. Because MDB can process a large number of concurrent messages, it is very suitable for some message gateway products. If a service is executed for a long time and the execution result does not need to be reported to the user in real time, MDB is also suitable for use. If the order is successful, send an email or text message to the user.

An MDB usually implements the messagelistener interface, which defines the onmessage () method. Bean uses it to process received JMS messages.

Package javax. JMS; public interface messagelistener {public void onmessage (message );}
When the container detects that a message arrives at the target address waiting for the bean, the container calls the onmessage () method to pass the message as a parameter to the MDB. MDB decides how to process the message in onmessage. You can use annotations to specify which Destination Address (destination) The MDB listens ). When MDB is deployed, the container reads the configuration information.

Message-driven Bean ):

@ Messagedriven (activationconfig = {@ activationconfigproperty (propertyname = "destinationtype", propertyvalue = "javax. JMS. queue "), @ activationconfigproperty (propertyname =" destination ", propertyvalue =" queue/foshanshop "), @ activationconfigproperty (propertyname =" acknowledgemode ", propertyvalue = "auto-acknowledge")}) public class printbean implements messagelistener {public void onmessage (Message MSG ){}}

Package cssage; import javax. EJB. activationconfigproperty; import javax. EJB. messagedriven; import javax. JMS. jmsexception; import javax. JMS. message; import javax. JMS. messagelistener; import javax. JMS. textmessage; @ messagedriven (activationconfig = {@ activationconfigproperty (propertyname = "destinationtype", propertyvalue = "javax. JMS. queue "), @ activationconfigproperty (propertyname =" destination ", propertyva Lue = "queue/itmqueue"), // when we use a container to manage transactions, the attribute setting of acknowledgemode is meaningless, // The automatic confirmation mode can be omitted or not ,. @ Activationconfigproperty (propertyname = "acknowledgemode", propertyvalue = "auto-acknowledge")}) public class messagedrivenbean implements messagelistener {@ overridepublic void onmessage (message) {/*** when the container detects that messagedrivenbean is the message-driven bean and the target address it listens to has a message, * it uses the message as the input parameter, the onmessage method of the message-driven bean is passed in, and the message can be processed in the method. How does the container know the target address of the message-driven bean * It listens, at this time, we need to use annotations to tell the container which target address the message-driven bean listens for and the type of the target address * // because the sent message is of the text type: textmessage MSG = (textmessage) message; try {system. out. println (MSG. gettext ();} catch (jmsexception e) {e. printstacktrace ();}}}
JNDI:

Java. Naming. Factory. Initial = org. jnp. Interfaces. namingcontextfactory
Java. Naming. provider. url = localhost \: 1099

  After the message-driven bean is developed, it must be packaged and deployed.

Compile build. xml and publish the message-driven bean to JBoss. After the message-driven bean is successfully published, the message is normally printed to the console in the console.

  Once the message-driven bean is deployed in JBoss, the container obtains the message from the target address based on the bean configuration information, passes it into the onmessage method, and executes the content in the method.

Through this example, we can also find that JMS programming allows the sender and receiver to be online at different times. That is to say, when a message is sent, the message receiver may not be online. The message receiver can also obtain the message when logging on to the system. In addition, there is no direct association between message receivers and message senders. The two are well decoupled.


Build. xml

<XML version = "1.0" encoding = "UTF-8"> <! -- Name indicates the project name. Basedir refers to the same directory as build. xml --> <! -- (1) basedir indicates the path of the project. --> <Project name = "messagedriverbean" basedir = "."> <! -- Directory of the project source file. --> <Property name = "src. dir" value = "$ {basedir} \ SRC"/> <! -- Point to the system variable in the environment variable --> <property environment = "env"/> <! -- Points to the jboss_home variable in the system variable. You can find the installation address of jboss_home --> <property name = "JBoss. home "value =" $ {Env. jboss_home} "/> <property name =" jbosnfig "value =" default "/> <! -- Directory of the class file --> <property name = "build. dir "value =" $ {basedir} \ build "/> <path id =" build. classpath "> <! -- Contains all jar files in the client path --> <fileset dir = "$ {JBoss. home} \ Client "> <include name = "*. jar "/> </fileset> <pathelement location =" $ {build. dir} "/> </path> <target name =" prepare "> <Delete dir =" $ {build. dir} "/> <mkdir dir =" $ {build. dir} "/> </Target> <! -- Depends = "prepare" ensure that the above code is executed first. Execute the following code --> <target name = "compile" depends = "prepare" Description = "compile"> <! -- Class is stored in the destdir directory. You must create the javac directory before calling it --> <javac srcdir = "$ {SRC. dir} "destdir =" $ {build. dir} "> <classpath refID =" build. classpath "/> </javac> </Target> <target name =" ejbjar "depends =" compile "Description =" Create an EJB release package "> <jar jarfile =" $ {basedir }\\ {ant. project. name }. jar "> <fileset dir =" $ {build. dir} "> <include name = "**/*. class "/> </fileset> </jar> </Target> <target name =" deploy "depends =" ejbjar "Description =" Publish EJB "> <copy file =" $ {basedir }\\ {ant. project. name }. jar "todir =" $ {JBoss. home} \ Server \ $ {jbosnfig} \ deploy "/> </Target> <target name =" undeploy "Description =" Uninstall EJB "> <delete file =" $ {JBoss. home} \ Server \ $ {jbosnfig} \ deploy \ $ {ant. project. name }. jar "/> </Target> </Project>

  This section describes how to send and receive messages of the queue type. That is, the message sending and receiving of the publishing/subscription transmission model. In this model, messages can be accepted by multiple receivers.

Method 2:Send and receive messages in the publish/subscribe Transfer Model.

  

Package CN. ITM. APP; import javax. JMS. destination; import javax. JMS. messageproducer; import javax. JMS. queuesession; import javax. JMS. textmessage; import javax. JMS. topicconnection; import javax. JMS. topicconnectionfactory; import javax. JMS. topicsession; import javax. naming. initialcontext; public class topicsender {public static void main (string [] ARGs) {try {initialcontext CTX = new initialcontext (); topicconnectionfactory factory = (topicconnectionfactory) CTX. lookup ("topicconnectionfactory"); topicconnection conn = factory. createtopicconnection (); topicsession session = Conn. createtopicsession (false, queuesession. auto_acknowledge); destination Destination = (destination) CTX. lookup ("Topic/itmtopic"); messageproducer producer = session. createproducer (destination); textmessage MSG = session. createtextmessage ("Hello, this is my first topic message"); producer. send (MSG); Session. close (); Conn. close (); system. out. println ("sent");} catch (exception e) {e. printstacktrace ();}}}
Package cssage; import javax. EJB. activationconfigproperty; import javax. EJB. messagedriven; import javax. JMS. jmsexception; import javax. JMS. message; import javax. JMS. messagelistener; import javax. JMS. textmessage; @ messagedriven (activationconfig = {@ activationconfigproperty (propertyname = "destinationtype", propertyvalue = "javax. JMS. topic "), @ activationconfigproperty (propertyname =" destination ", propertyvalue =" Topic/itmtopic ")}) public class receivebean implements messagelistener {@ override public void onmessage (message) {textmessage MSG = (textmessage) message; try {system. out. println (this. getclass () + MSG. gettext ();} catch (jmsexception e) {e. printstacktrace ();}}}
Package cssage; import javax. EJB. activationconfigproperty; import javax. EJB. messagedriven; import javax. JMS. jmsexception; import javax. JMS. message; import javax. JMS. messagelistener; import javax. JMS. textmessage; @ messagedriven (activationconfig = {@ activationconfigproperty (propertyname = "destinationtype", propertyvalue = "javax. JMS. topic "), @ activationconfigproperty (propertyname =" destination ", propertyvalue =" Topic/itmtopic ")}) public class receiveotherbean implements messagelistener {@ override public void onmessage (message) {textmessage MSG = (textmessage) message; try {system. out. println (this. getclass () + MSG. gettext ();} catch (jmsexception e) {e. printstacktrace ();}}}

  Procedure:

  Start JBoss first, and then release the itm-service.xml.

  Next, release build. xml.

  
The two message-driven beans have been developed, and both of them will get the message from the target address. Now, they are published. However, the topic message just sent is not displayed on the console. That is because for a topic message, if the receiver does not listen to the topic message at that time, the message cannot be obtained. Although we deploy it in JBoss, it cannot get messages because it didn't listen to the target address of the topic at the time.
Now execute topicsender. Java and you will see the two message-driven beans get the messages. Console output:

  Info [stdout] class cssage. receiveotherbean hello, this is my first topic message
Info [stdout] class cssage. receivebean hello, this is my first topic message

This proves that multiple receivers can obtain this message for the publishing/subscription transmission model.

Test the sending of the queue type and run queuesender. java. For sending of the queue type, a message can only be received by one receiver.

  

 

Original article: http://www.educity.cn/wenda/357315.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.