ejb2.0消息驱动bean的开发(JBOSS4.0.4.GA 环境)

本文介绍如何使用消息驱动Bean实现异步业务处理,包括开发步骤、配置文件示例及客户端测试方法。

 

          消息驱动bean主要使用在异步的业务中,比如用户在页面上查询了话费(余额,实时话费,语音,短信。。。),我们需要把用户这个行为记录到数据库中,就可以使用消息驱动bean。

           首先使用springAOP 拦截到 调用的 业务方法,发现是业务关注的方法的时候,在invoke 方法中发送一条消息到消息队列中去,(此业务场景我们使用 点对点的 消息发送模式)然后 ,消息驱动bean从监听的队列中取到消息,插入到数据库中。查询话费 和 将行为入库 是异步的,因此不会阻塞。不影响前台页面显示速度。

 

 

开发一个消息驱动bean 的步骤:

 

 

1.首先 写 消息驱动bean ,负责从消息队列中取消息,然后执行相应的业务方法

 

 

package cn.com.xinli.ejb.mdb;
import javax.ejb.EJBException;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.apache.log4j.Logger;

public class MDBean implements MessageDrivenBean,MessageListener
{
	Logger log=Logger.getLogger(MDBean.class);
	private transient MessageDrivenContext mdc = null;
	public void onMessage(Message message)
	{		
		if(message instanceof TextMessage)
		{
			TextMessage msg=(TextMessage) message; 
			try {
				log.info("接收到消息:"+msg.getText());
			} catch (JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else
		{
			log.info("消息类型不正确!"); 
		}
	}
	 public void ejbCreate() 
	 {
		  
	 }
	public void ejbRemove() throws EJBException
	{
		// TODO Auto-generated method stub
		
	}
	public void setMessageDrivenContext(MessageDrivenContext mdc)
			throws EJBException
	{
		this.mdc = mdc;
		// TODO Auto-generated method stub
	}

}

 

 

2. 配置 ejb-jar.xml

 

<?xml version="1.0" encoding="gb2312"?> 
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" 
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
	<description>ejb</description>
	<display-name>myEJBTest</display-name>
<enterprise-beans>

		
			<message-driven id="ejb_mdb">
			<ejb-name>mdb</ejb-name>
            <ejb-class>cn.com.xinli.ejb.mdb.MDBean</ejb-class>
           	<transaction-type>Bean</transaction-type>
           	<acknowledge-mode>Auto-acknowledge</acknowledge-mode>
           	<message-driven-destination>
            <destination-type>javax.jms.Queue</destination-type> 
            </message-driven-destination>
		</message-driven>
	</enterprise-beans>
</ejb-jar>

 

 

3. 配置 jboss.xml

 

<?xml version="1.0" encoding="gb2312"?>
<jboss>
	
	<message-driven>
        <ejb-name>mdb</ejb-name>    
        <configuration-name>Standard Message Driven Bean</configuration-name>
        <!-- 消息驱动bean 监听的消息队列的 JNDI
        <destination-jndi-name>queue/mdb</destination-jndi-name>  
        -->
      </message-driven> 
	</enterprise-beans>
</jboss>

 

 

4. 讲bean 打成jar包 放在 D:\jboss-4.0.4.GA\server\default\deploy 下

 

5. 在jboss中配置消息队列 也在 D:\jboss-4.0.4.GA\server\default\deploy 下 ,配置文件必须 符合  *-service.xml  的命名规范,这里我们叫 bsn-service.xml

 

<?xml version="1.0" encoding="UTF-8"?>

<!-- $Id: jbossmq-destinations-service.xml,v 1.4.6.1 2004/11/16 04:32:39 ejort Exp $ -->

<!-- 
   | This file defines the default Queues and Topics that JBossMQ
   | ships with.  The default Queues and Topics are used by the 
   | JBoss test suite and by the sample jms programs.
   |
   | You can add other destinations to this file, or you can create other
   | *-service.xml files to contain your application's destinations.
 -->

<server>
  <!-- Destination without a configured SecurityManager or without a 
       a SecurityConf will default to role guest with read=true, write=true,
       create=false.
  -->
  <mbean code="org.jboss.mq.server.jmx.Queue" 
	 name="jboss.mq.destination:service=Queue,name=queueRecordb">
	  <attribute name="JNDIName">queue/mdb</attribute> 
   <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
  </mbean>
</server>

  

 

6.发布

 

7.客户端测试,观察 JBOSS 控制台 会有

 

09:43:36,156 INFO  [MDBean] 接收到消息:你好

 

package cn.com.xinli.ejb.test;

import java.util.Properties;

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;

import org.apache.log4j.Logger;

public class Test
{

	static Logger log=Logger.getLogger(Test.class);
	/**
	 * @param args
	 */
	public static void main(String[] args)
    {
		
       
        Properties props = new Properties();
        props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
        props.setProperty("java.naming.provider.url", "localhost:1099");
        props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
        try
        {
            InitialContext ctx = new InitialContext(props);
            
        	QueueConnectionFactory factory=(QueueConnectionFactory)ctx.lookup("QueueConnectionFactory");
			QueueConnection conn=factory.createQueueConnection();
			
			QueueSession session=conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
			
			Destination destination=(Destination)ctx.lookup("queue/mdb");
			MessageProducer producer = session.createProducer(destination);
			
			TextMessage msg = session.createTextMessage("你好");
			producer.send(msg);
			log.info("发送消息成功!!");
            
            /*
            Object objRef = ctx.lookup("helloEJB");
            
            HelloWorldHome home = (HelloWorldHome) PortableRemoteObject.narrow(objRef, HelloWorldHome.class);
            
            HelloWorldRemote remote = home.create();
            
            log.info(remote.sayHello());
            */
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
}

  

 

备注:

 

1. 许多教程上说 必须要到   D:\jboss-4.0.4.GA\server\default\deploy  配置一个 消息队列 类似 bsn-service.xml

    其实这不是必要的

 

如果我们没有配置  a ,b

a.     <!-- 消息驱动bean 监听的消息队列的 JNDI-->
        <destination-jndi-name>queue/mdb</destination-jndi-name> 

b.   也没有配置 bsn-service.xml 那么JBOSS启动的时候发现没有队列和消息驱动bean 关联,则它会自己创建一个消息队列 ,这个消息对列的命名规范 是   : queue/消息驱动bean的jndi

 

      客户端就可以往这个队列 上发送消息。

 

2. 如果我们配置了 消息驱动bean 关联的队列 和 JBosS下的 bsn-service.xml ,那么我们就可以使用自定义的 队列的JNDI了 比如

 

  a. 配置 mdb 这个消息驱动bean 监听的 对列的JNDI 为

<destination-jndi-name>myqueue</destination-jndi-name> 

 

b.配置 bsn-service.xml的内容为

 

<?xml version="1.0" encoding="UTF-8"?>

<!-- $Id: jbossmq-destinations-service.xml,v 1.4.6.1 2004/11/16 04:32:39 ejort Exp $ -->

<!-- 
   | This file defines the default Queues and Topics that JBossMQ
   | ships with.  The default Queues and Topics are used by the 
   | JBoss test suite and by the sample jms programs.
   |
   | You can add other destinations to this file, or you can create other
   | *-service.xml files to contain your application's destinations.
 -->

<server>
  <!-- Destination without a configured SecurityManager or without a 
       a SecurityConf will default to role guest with read=true, write=true,
       create=false.
  -->
  <mbean code="org.jboss.mq.server.jmx.Queue" 
	 name="jboss.mq.destination:service=Queue,name=queueRecordb">
	  <attribute name="JNDIName">myqueue</attribute> 
   <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
  </mbean>
</server>

  

 

 

 

 

那么客户端就可以往 我们自定义的 队列的JDNI上  myqueue  发送消息了

 

3.  在JBOSS中有两个默认的工厂 一个是 QueueConnectionFactory

另外一个是 TopicConnectionFactory ,这两个工厂是由JBOSS容器帮我们建立的 ,不需要我们去配置,而在websphere 上建立消息驱动bean的时候 就需要我们配置 连接工厂了

 

4. 以上模拟的的消息驱动bean 是队列模式 ,主题模式何其类似 

 


附件中式 全部的工程代码

 

 

 

 

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值