zoukankan      html  css  js  c++  java
  • JBOSS7搭载EJB3之消息驱动Bean


      消息驱动bean(message driven bean)MDB--用于处理基于消息的组件


    下面借用几张黎老师讲课的图片  很清晰  就直接上图了



    队列方式 Queue  即点对点PTP  一个消息只能传递给一个接收者





    环状方式  Topic  即pub/sub 发布/订阅  一条消息可以有多个接收方


    对于jboss7中 默认的standalone中 是没有jms的配置的  但是standalone-full里面有jms的配置 所以将jboss-as-7.1.1.Finalstandaloneconfiguration 下的standalone-full.xml改为standalone.xml  即可  打开修改的文件 找到jms测试的queue、topic的目的地址的配置

    <jms-destinations>
                        <jms-queue name="testQueue">
                            <entry name="queue/test"/>
                            <entry name="java:jboss/exported/jms/queue/test"/>
                        </jms-queue>
                        <jms-topic name="testTopic">
                            <entry name="topic/test"/>
                            <entry name="java:jboss/exported/jms/topic/test"/>
                        </jms-topic>
                    </jms-destinations>

    记住它的名字  一会在代码中要用

    还有一个就是连接工厂

    <jms-connection-factories>
                        <connection-factory name="InVmConnectionFactory">
                            <connectors>
                                <connector-ref connector-name="in-vm"/>
                            </connectors>
                            <entries>
                                <entry name="java:/ConnectionFactory"/>
                            </entries>
                        </connection-factory>
                        <connection-factory name="RemoteConnectionFactory">
                            <connectors>
                                <connector-ref connector-name="netty"/>
                            </connectors>
                            <entries>
                                <entry name="RemoteConnectionFactory"/>
                                <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                            </entries>
                        </connection-factory>
                        <pooled-connection-factory name="hornetq-ra">
                            <transaction mode="xa"/>
                            <connectors>
                                <connector-ref connector-name="in-vm"/>
                            </connectors>
                            <entries>
                                <entry name="java:/JmsXA"/>
                            </entries>
                        </pooled-connection-factory>
                    </jms-connection-factories>



    好了 现在开始使用PTP方式产生消息

    package com.undergrowth.hello.impl;
    
    import javax.annotation.Resource;
    import javax.ejb.Remote;
    import javax.ejb.Stateless;
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.MessageProducer;
    import javax.jms.QueueConnection;
    import javax.jms.QueueConnectionFactory;
    import javax.jms.QueueSession;
    import javax.jms.TextMessage;
    
    import com.undergrowth.hello.JmsMessProducer;
    
    
    /**
     * 
     * @author Administrator
     *
     */
    @Stateless
    @Remote(JmsMessProducer.class)
    public class JmsMessProducerBean implements JmsMessProducer {
    
    	//注入连接工厂和目的地
    	@Resource(mappedName="java:/ConnectionFactory")
    	private QueueConnectionFactory conFactory;
    	@Resource(mappedName="java:/queue/test")
    	private Destination destination;
    	
    	@Override
    	public void send(String what) {
    		// TODO Auto-generated method stub
    		QueueConnection queueConnection=null;
    		QueueSession session=null;
    		try {
    			//创建队列连接
    			 queueConnection=conFactory.createQueueConnection();
    			 session=queueConnection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
    			 //创建消息提供者
    			MessageProducer producer=session.createProducer(destination);
    			TextMessage message=session.createTextMessage(what);
    			//发送消息
    			producer.send(message);
    			System.out.println(JmsMessProducerBean.class+":	发送的消息为:	"+message.getText());
    		} catch (JMSException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}finally{
    			try {
    				session.close();
    				queueConnection.close();
    			} catch (JMSException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			
    		}
    		
    	}
    
    }
    

    远程接口

    package com.undergrowth.hello;
    
    /**
     * 消息的发送者
     * @author Administrator
     *
     */
    public interface JmsMessProducer {
    	public void send(String what);
    }
    

    使用MDB注册到JBOSS中 接收PTP消息

    package com.undergrowth.hello.impl;
    
    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",propertyValue="java:/queue/test")
    })
    public class JmsMessageConsumer implements MessageListener {
    
    	@Override
    	public void onMessage(Message msg) {
    		// TODO Auto-generated method stub
    		TextMessage message=(TextMessage) msg;
    		try {
    			System.out.println(JmsMessageConsumer.class+":	接收到消息为:	"+message.getText());
    		} catch (JMSException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    
    }
    


    再看另一种方式  Topic  pub/sub

    package com.undergrowth.hello.impl;
    
    import javax.annotation.Resource;
    import javax.ejb.Remote;
    import javax.ejb.Stateless;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.MessageProducer;
    import javax.jms.TextMessage;
    import javax.jms.TopicConnection;
    import javax.jms.TopicConnectionFactory;
    import javax.jms.TopicSession;
    
    import com.undergrowth.hello.JmsMessTopicProducer;
    
    @Stateless
    @Remote(JmsMessTopicProducer.class)
    public class JmsMessTopicProducerBean implements JmsMessTopicProducer{
    
    	//注入连接工厂和目的地
    		@Resource(mappedName="java:/ConnectionFactory")
    		private TopicConnectionFactory conFactory;
    		@Resource(mappedName="java:/topic/test")
    		private Destination destination;
    	
    	@Override
    	public void send(String what) {
    		// TODO Auto-generated method stub
    		TopicConnection connection=null;
    		TopicSession session=null;
    		try {
    			 connection=conFactory.createTopicConnection();
    			 session=connection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
    			 MessageProducer producer=session.createProducer(destination);
    			 TextMessage message=session.createTextMessage(what);
    			 producer.send(message);
    			 System.out.println(JmsMessTopicProducerBean.class+"	 发送的消息为:	"+what);
    		} catch (JMSException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}finally{
    			try {
    				session.close();
    				connection.close();
    			} catch (JMSException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			
    		}
    		
    	}
    
    }
    

    远程接口

    package com.undergrowth.hello;
    
    public interface JmsMessTopicProducer extends JmsMessProducer{
    		
    }
    

    使用多个消息驱动bean 来接收pub/sub 消息

    package com.undergrowth.hello.impl;
    
    import javax.ejb.ActivationConfigProperty;
    import javax.ejb.MessageDriven;
    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="java:/topic/test")
    })
    public class JmsMessTopicConsumer implements MessageListener{
    
    	@Override
    	public void onMessage(Message msg) {
    		// TODO Auto-generated method stub
    		TextMessage message=(TextMessage) msg;
    		try {
    			System.out.println(JmsMessTopicConsumer.class+"	 接收到的消息为:	"+message.getText());
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    	
    }
    

    另外一个

    package com.undergrowth.hello.impl;
    
    import javax.ejb.ActivationConfigProperty;
    import javax.ejb.MessageDriven;
    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="java:/topic/test")
    })
    public class JmsMessTopicConsumerOther implements MessageListener{
    
    	@Override
    	public void onMessage(Message msg) {
    		// TODO Auto-generated method stub
    		TextMessage message=(TextMessage) msg;
    		try {
    			System.out.println(JmsMessTopicConsumerOther.class+"	 接收到的消息为:	"+message.getText());
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    	
    }
    


    好了 服务端写好了 打包发布 ant 的build.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- ================================================ -->
    <!-- Sample buildfile for jar components -->
    <!-- -->
    <!-- ================================================ -->
    <project name="HelloWorld"  basedir=".">
        <!-- 定义属性 -->
        <property name="src.dir" value="${basedir}src" />
        <property environment="env"  />
        <property name="jboss.home" value="${env.JBOSS_HOME}"/>
        <property name="jboss.server.home" value="standalone"  />
        <property name="dep" value="deployments"  />
        <property name="build.dir" value="${basedir}uild"  />
    
        <path id="build.classpath">
        	<fileset dir="${basedir}lib">
        		<include name="*.jar" />
        	</fileset>
        	<pathelement location="${build.dir}" />
        </path>
    
    	<!-- - - - - - - - - - - - - - -->
    	<!-- target: init -->
    	<!-- - - - - - - - - - - - - - -->
    	<target name="init">
    		<delete dir="${build.dir}"></delete>
    		<mkdir dir="${build.dir}"></mkdir>
    	</target>
    
    	<!-- ========================= -->
    	<!-- target: compile -->
    	<!-- ========================= -->
    	<target name="compile" depends="init"
    		description="--> compile  this component" >
    
    		<javac srcdir="${src.dir}" destdir="${build.dir}" includes="com/**">
    			<classpath refid="build.classpath" />
    		</javac>
    	</target>
    	
    	<!-- 打包 -->
    	<target name="ejbjar" depends="compile" description="打包ejb">
    	   <jar jarfile="${basedir}${ant.project.name}.jar">
    	   	<fileset dir="${build.dir}">
    	   		<include name="**/*.class"></include>
    	   	</fileset>
    	   	<metainf dir="${src.dir}META-INF"></metainf>
    	   </jar>
    	</target>
    
        <!-- 部署 -->
        <target name="delopy" depends="ejbjar" description="部署ejb">
        	<copy file="${basedir}${ant.project.name}.jar"  todir="${jboss.home}${jboss.server.home}${dep}" />
        </target>
        
        <!-- 卸载ejb -->
        <target name="undeploy" description="卸载ejb">
          <delete file="${jboss.home}${jboss.server.home}${dep}${ant.project.name}.jar"></delete>
        </target>
        
    	<!-- 打包接口 -->
    	<target name="package_inter" depends="compile" description="打包接口">
    		<jar jarfile="${basedir}${ant.project.name}Interface.jar">
    			   	<fileset dir="${build.dir}">
    			   		<exclude name="**/impl/*.class"></exclude>
    			   	</fileset>
    			   </jar>
    	</target>
    	
    	
    
    </project>
    


    jboss 控制台

    22:04:59,587 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-3) JNDI bindings for session bean named JmsMessProducerBean in deployment unit deployment "HelloWorld.jar" are as follows:
    
    	java:global/HelloWorld/JmsMessProducerBean!com.undergrowth.hello.JmsMessProducer
    	java:app/HelloWorld/JmsMessProducerBean!com.undergrowth.hello.JmsMessProducer
    	java:module/JmsMessProducerBean!com.undergrowth.hello.JmsMessProducer
    	java:jboss/exported/HelloWorld/JmsMessProducerBean!com.undergrowth.hello.JmsMessProducer
    	java:global/HelloWorld/JmsMessProducerBean
    	java:app/HelloWorld/JmsMessProducerBean
    	java:module/JmsMessProducerBean
    22:04:59,576 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-3) JNDI bindings for session bean named JmsMessTopicProducerBean in deployment unit deployment "HelloWorld.jar" are as follows:
    
    	java:global/HelloWorld/JmsMessTopicProducerBean!com.undergrowth.hello.JmsMessTopicProducer
    	java:app/HelloWorld/JmsMessTopicProducerBean!com.undergrowth.hello.JmsMessTopicProducer
    	java:module/JmsMessTopicProducerBean!com.undergrowth.hello.JmsMessTopicProducer
    	java:jboss/exported/HelloWorld/JmsMessTopicProducerBean!com.undergrowth.hello.JmsMessTopicProducer
    	java:global/HelloWorld/JmsMessTopicProducerBean
    	java:app/HelloWorld/JmsMessTopicProducerBean
    	java:module/JmsMessTopicProducerBean



    第三方客户端测试

    queue测试

    package com.undergrowth.ejb3.client;
    
    import java.util.Hashtable;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    import com.undergrowth.hello.HelloWorldLocal;
    import com.undergrowth.hello.JmsMessProducer;
    
    public class JmsClient {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		try {
    			JmsMessProducer messProducer=lookupRemoteHelloWorldBean();
    			messProducer.send("jms文本消息,明天又要上班了!!!");
    		} catch (NamingException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    	}
    
    	 public static JmsMessProducer lookupRemoteHelloWorldBean() throws NamingException {
    	        final Hashtable jndiProperties = new Hashtable();
    	        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    	        final Context context = new InitialContext(jndiProperties);
    	        // The app name is the application name of the deployed EJBs. This is typically the ear name
    	        // without the .ear suffix. However, the application name could be overridden in the application.xml of the
    	        // EJB deployment on the server.
    	        // Since we haven't deployed the application as a .ear, the app name for us will be an empty string
    	        final String appName = "";
    	        // This is the module name of the deployed EJBs on the server. This is typically the jar name of the
    	        // EJB deployment, without the .jar suffix, but can be overridden via the ejb-jar.xml
    	        // In this example, we have deployed the EJBs in a jboss-as-ejb-remote-app.jar, so the module name is
    	        // jboss-as-ejb-remote-app
    	        final String moduleName = "HelloWorld";
    	        // AS7 allows each deployment to have an (optional) distinct name. We haven't specified a distinct name for
    	        // our EJB deployment, so this is an empty string
    	        final String distinctName = "";
    	        // The EJB name which by default is the simple class name of the bean implementation class
    	        final String beanName = "JmsMessProducerBean";
    	        // the remote view fully qualified class name
    	       // final String viewClassName = HelloWorldRemote.class.getName();
    	        final String viewClassName = JmsMessProducer.class.getName();
    	        // let's do the lookup
    	        return (JmsMessProducer) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
    	        
    	 }
    	 
    	
    }
    

    控制台

    22:10:18,816 INFO  [stdout] (EJB default - 3) class com.undergrowth.hello.impl.JmsMessProducerBean:	发送的消息为:	jms文本消息,明天又要上班了!!!
    
    22:10:19,226 INFO  [stdout] (Thread-162 (HornetQ-client-global-threads-28566125)) class com.undergrowth.hello.impl.JmsMessageConsumer:	接收到消息为:	jms文本消息,明天又要上班了!!!

    看下jboss的管理控制台



    队列消息添加1  运行一次客户端  加一次


    topic方式 测试

    package com.undergrowth.ejb3.client;
    
    import java.util.Hashtable;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    import com.undergrowth.hello.HelloWorldLocal;
    import com.undergrowth.hello.JmsMessProducer;
    import com.undergrowth.hello.JmsMessTopicProducer;
    
    public class JmsTopicClient {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		try {
    			JmsMessProducer messProducer=lookupRemoteHelloWorldBean();
    			messProducer.send("jms的topic方式文本消息,明天又要上班了!!!");
    		} catch (NamingException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    	}
    
    	 public static JmsMessTopicProducer lookupRemoteHelloWorldBean() throws NamingException {
    	        final Hashtable jndiProperties = new Hashtable();
    	        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    	        final Context context = new InitialContext(jndiProperties);
    	        // The app name is the application name of the deployed EJBs. This is typically the ear name
    	        // without the .ear suffix. However, the application name could be overridden in the application.xml of the
    	        // EJB deployment on the server.
    	        // Since we haven't deployed the application as a .ear, the app name for us will be an empty string
    	        final String appName = "";
    	        // This is the module name of the deployed EJBs on the server. This is typically the jar name of the
    	        // EJB deployment, without the .jar suffix, but can be overridden via the ejb-jar.xml
    	        // In this example, we have deployed the EJBs in a jboss-as-ejb-remote-app.jar, so the module name is
    	        // jboss-as-ejb-remote-app
    	        final String moduleName = "HelloWorld";
    	        // AS7 allows each deployment to have an (optional) distinct name. We haven't specified a distinct name for
    	        // our EJB deployment, so this is an empty string
    	        final String distinctName = "";
    	        // The EJB name which by default is the simple class name of the bean implementation class
    	        final String beanName = "JmsMessTopicProducerBean";
    	        // the remote view fully qualified class name
    	       // final String viewClassName = HelloWorldRemote.class.getName();
    	        final String viewClassName = JmsMessTopicProducer.class.getName();
    	        // let's do the lookup
    	        return (JmsMessTopicProducer) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
    	        
    	 }
    	 
    	
    }
    


    控制台

    22:13:45,928 INFO  [stdout] (EJB default - 5) class com.undergrowth.hello.impl.JmsMessTopicProducerBean	 发送的消息为:	jms的topic方式文本消息,明天又要上班了!!!
    
    22:13:45,931 INFO  [stdout] (Thread-170 (HornetQ-client-global-threads-28566125)) class com.undergrowth.hello.impl.JmsMessTopicConsumerOther	 接收到的消息为:	jms的topic方式文本消息,明天又要上班了!!!
    
    22:13:45,938 INFO  [stdout] (Thread-174 (HornetQ-client-global-threads-28566125)) class com.undergrowth.hello.impl.JmsMessTopicConsumer	 接收到的消息为:	jms的topic方式文本消息,明天又要上班了!!!


    两个接收者都收到消息了


    jboss管理界面






    好了 

    参看文档:

    http://my.oschina.net/zhaoqian/blog/90796

    http://dujianmeng.iteye.com/blog/1552685




    记录学习的脚步  

  • 相关阅读:
    Windows网络编程经验小结
    异步Socket服务器与客户端
    用C#实现C/S模式下软件自动在线升级
    Linux 安装字体
    word 生成目录
    Linux sar使用
    yum 使用说明
    HASH JOIN算法
    row cache lock
    cursor: pin S
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275552.html
Copyright © 2011-2022 走看看