ActiveMQ 实践之路(四) ActiveMQ 4.x +JBoss 4.x MDP实战篇
在<<ActiveMQ 实践之路(三) ActiveMQ 4.x +JBoss 4.x 整合篇 >>里面我们比较详细的讲解了ActiveMQ与JBoss的整合,
既然选择了JBoss,那么项目里面或多或少都会使用到EJB,下面我们就详细地介绍如何在ActiveMQ 4.x+JBOSS 4.x环境下开发
Message Driven Bean,并且与使用jbossMQ在配置上作了比较详细地比较。这里的OrderMessage 仅仅是一个自动生成的Message Driven Bean,在onMessage方法里面,作日志输入。
一. 配置ejb-jar.xml
1. ejb-jar.xml 不能使用XML DTD,需要使用XML Schema(XSD)
很多朋友可能使用XDoclet来生成ejb-jar.xml,我这里直接使用XDoclet生成的ejb-jar.xml是
<!---->
但是在ActiveMQ+JBoss配置中间需要使用新的XML Schema才能完成对ra的定义,如下.
xml 代码
- <ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">
2. ejb-jar.xml 直接使用JBossMQ的Message DriverBean 和使用ActiveMQ RA配置的区别
(1) .使用JBossMQ的MessageDrivenBean的 ejb-jar.xml配置
xml 代码
-
- <message-driven>
- <description>
-
- description>
- <display-name>Name for OrderMessagedisplay-name>
- <ejb-name>OrderMessageejb-name>
- <ejb-class>com.mostone.ejb.OrderMessageejb-class>
- <transaction-type>Containertransaction-type>
- <acknowledge-mode>Auto-acknowledgeacknowledge-mode>
- <message-driven-destination>
- <destination-type>javax.jms.Queuedestination-type>
- message-driven-destination>
- message-driven>
(2). 使用ActiveMQ RA配置的MessageDrivenBean的ejb-jar.xml配置
xml 代码
-
- <message-driven>
- <description>
-
- description>
- <display-name>Name for OrderMessagedisplay-name>
- <ejb-name>OrderMessageejb-name>
- <ejb-class>com.mostone.ejb.OrderMessageejb-class>
- <transaction-type>Containertransaction-type>
- <acknowledge-mode>Auto-acknowledgeacknowledge-mode>
-
- <activation-config>
- <activation-config-property>
- <activation-config-property-name>destinationactivation-config-property-name>
- <activation-config-property-value>queue.outboundactivation-config-property-value>
- activation-config-property>
- <activation-config-property>
- <activation-config-property-name>destinationTypeactivation-config-property-name>
- <activation-config-property-value>javax.jms.Queueactivation-config-property-value>
- activation-config-property>
- activation-config>
- message-driven>
其中destination,destinationType是ra.xml里面提供的配置属性,(这里官方的文档是Destination,DestinationType, 而实际上activemq-ra.rar里面的ra.xml是destination,destinationType,注意大小写区别)
二. 配置jboss.xml
大部分配置都是在jboss.xml里面.
1.使用JBossMQ 和使用ActiveMQ RA配置Message Driven Bean的区别
1.) 使用JBossMQ 的配置
xml 代码
- <message-driven>
- <ejb-name>OrderMessageejb-name>
- <destination-jndi-name>queue/testQueuedestination-jndi-name>
- message-driven>
2.) 使用ActiveMQ RA的配置
xml 代码
- <message-driven>
- <ejb-name>ActiveMQMDPejb-name>
-
- <resource-adapter-name>activemq-ra.rarresource-adapter-name>
-
- <configuration-name>ActiveMQ Message Driven Beanconfiguration-name>
- message-driven>
2. jboss.xml 配置invoker proxy和container 支持ActiveMQ RA
xml 代码
- <invoker-proxy-bindings>
- <invoker-proxy-binding>
- <name>activemq-message-driven-beanname>
- <invoker-mbean>defaultinvoker-mbean>
- <proxy-factory>org.jboss.ejb.plugins.inflow.JBossMessageEndpointFactoryproxy-factory>
- <proxy-factory-config>
- <endpoint-interceptors>
- <interceptor>org.jboss.proxy.ClientMethodInterceptorinterceptor>
- <interceptor>org.jboss.ejb.plugins.inflow.MessageEndpointInterceptorinterceptor>
- <interceptor>org.jboss.proxy.TransactionInterceptorinterceptor>
- <interceptor>org.jboss.invocation.InvokerInterceptorinterceptor>
- endpoint-interceptors>
- proxy-factory-config>
- invoker-proxy-binding>
- invoker-proxy-bindings>
MessageDrivenBean的container配置,这里的<container-name></container-name>必须和上面的<configuration-name></configuration-name>相同 才能起作用.
xml 代码
- <container-configurations>
- <container-configuration>
- <container-name>ActiveMQ Message Driven Beancontainer-name>
- <call-logging>falsecall-logging>
- <invoker-proxy-binding-name>activemq-message-driven-beaninvoker-proxy-binding-name>
- <container-interceptors>
- <interceptor>org.jboss.ejb.plugins.ProxyFactoryFinderInterceptorinterceptor>
- <interceptor>org.jboss.ejb.plugins.LogInterceptorinterceptor>
- <interceptor>org.jboss.ejb.plugins.RunAsSecurityInterceptorinterceptor>
-
- <interceptor transaction="Container">org.jboss.ejb.plugins.TxInterceptorCMTinterceptor>
- <interceptor transaction="Container">org.jboss.ejb.plugins.CallValidationInterceptorinterceptor>
- <interceptor transaction="Container" metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptorinterceptor>
- <interceptor transaction="Container">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptorinterceptor>
-
- <interceptor transaction="Bean">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptorinterceptor>
- <interceptor transaction="Bean">org.jboss.ejb.plugins.MessageDrivenTxInterceptorBMTinterceptor>
- <interceptor transaction="Bean">org.jboss.ejb.plugins.CallValidationInterceptorinterceptor>
- <interceptor transaction="Bean" metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptorinterceptor>
- <interceptor>org.jboss.resource.connectionmanager.CachedConnectionInterceptorinterceptor>
- container-interceptors>
- <instance-pool>org.jboss.ejb.plugins.MessageDrivenInstancePoolinstance-pool>
- <instance-cache>instance-cache>
- <persistence-manager>persistence-manager>
- <container-pool-conf>
- <MaximumSize>100MaximumSize>
- container-pool-conf>
- container-configuration>
- container-configurations>
以上就是ActiveMQ+JBoss InBound 的配置
三.在Servlet中通过发送消息,验证上面的Message Driven Bean
为了验证这个MessageDrivenBean能够正常工作,我使用一个很简单的servlet向这个queue发送消息,前一篇的activemq-ds.xml 已经提供在启动的时候绑定了JNDI activemq/QueueConnectionFactory,activemq/queue/outbound,我们直接使用就行了,
java 代码
- try {
- initialContext = new InitialContext();
- QueueConnectionFactory connectionFactory = (QueueConnectionFactory) initialContext
- .lookup("java:activemq/QueueConnectionFactory");
- Connection con=connectionFactory.createConnection();
- Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- Queue queue = (Queue) initialContext.lookup("activemq/queue/outbound");
- MessageProducer producer = session.createProducer(queue);
- TextMessage txtMessage = session.createTextMessage();
- txtMessage.setText("A");
- producer.send(txtMessage);
- producer.close();
- session.close();
- con.close();
-
- } catch (NamingException e) {
-
- e.printStackTrace();
- } catch (JMSException e) {
-
- e.printStackTrace();
- }
四.关于durable方式订阅topic的补充说明
使用durable方式,你需要在ejb-jar.xml中额外的配置,subscriptionDurability,clientId,subscriptionName
xml 代码
- <activation-config>
- <activation-config-property>
- ......
- <activation-config-property>
- <activation-config-property-name>subscriptionDurabilityactivation-config-property-name>
- <activation-config-property-value>Durableactivation-config-property-value>
- activation-config-property>
- <activation-config-property>
- <activation-config-property-name>clientIdactivation-config-property-name>
- <activation-config-property-value>fooactivation-config-property-value>
- activation-config-property>
- <activation-config-property>
- <activation-config-property-name>subscriptionNameactivation-config-property-name>
- <activation-config-property-value>baractivation-config-property-value>
- activation-config-property>
- ......
- activation-config-property>
- activation-config>
ok 这样就可以使用durable方式订阅topic了。
参考文档:
JBoss Integration
ActiveMQ Inbound Communication
ActiveMQ Outbound Communication