ActiveMQ(5.10.0) - Spring Support
2016-01-15 11:39
441 查看
Maven Dependency:
View Code
2. Test Code:
2. Test Code:
2. MyQueueMessageListener:
One thing to bear in mind with JmsTemplate is that by default it will create a new connection, session, producer for each message sent - then close them all down again. This is very inefficient! It is done like this to work in EJB containers which tend to use a special ConnectionFactory which does pooling.
If you are not using a JCA container to manage your JMS connections, we recommend you use our pooling JMS connection provider, (org.apache.activemq.pool.PooledConnectionFactory) from the
e.g.
The
Note: while the
If you are creating a collection of consumers (for example, for multi-threaded message consumption), you should consider keeping a low prefetch value (e.g. 10 or 20), to ensure that all messages don't end up going to just one of the consumers.
Spring's MessagListenerContainer should be used for message consumption. This provides all the power of MDBs - efficient JMS consumption and pooling of the message listeners - but without requiring a full EJB container.
You can use the
<dependencies> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>${activemq.version}</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-jaas</artifactId> <version>${activemq.version}</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-spring</artifactId> <version>${activemq.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> </dependency> </dependencies>
View Code
Using Spring to Send JMS Messages
1. applicationContext.xml:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.huey.hello" /> <!-- 配置 JMS 连接工厂 --> <bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://10.1.242.146:61616" /> </bean> <!-- 配置 JMS 模版 --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory" /> <!-- 指定默认的目的地 --> <property name="defaultDestination" ref="helloQueue" /> </bean> <!-- 配置消息的目的地 --> <bean id="helloQueue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg index="0" value="example.HelloQueue" /> </bean> </beans>
2. Test Code:
public class AMQTest extends SpringTest { @Resource(name = "jmsTemplate") JmsTemplate jmsTemplate; @Resource(name = "helloQueue") Destination helloQueue; @Test public void testSendMessage() throws Exception { jmsTemplate.send(helloQueue, new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createTextMessage("Hello, ActiveMQ!"); } }); System.out.println("Send the message successfully."); } }
Using Spring to Receive JMS Messages Synchronously
1. applicationContext.xml:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.huey.hello" /> <bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://10.1.242.146:61616" /> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory" /> <property name="defaultDestination" ref="helloQueue" /> </bean> <bean id="helloQueue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg index="0" value="example.HelloQueue" /> </bean> </beans>
2. Test Code:
public class AMQTest extends SpringTest { @Resource(name = "jmsTemplate") JmsTemplate jmsTemplate; @Resource(name = "helloQueue") Destination helloQueue; @Test public void testReceiveSyncMessage() throws Exception { Message message = jmsTemplate.receive(); if (message == null) { System.out.println("There are not any messages."); return; } if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; System.out.println("Receive a text message: " + textMessage.getText()); } else { System.out.println("Receive a non-text message."); } } }
Using Spring to Receive JMS Messages Asynchronously
1. applicationContext.xml:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.huey.hello" /> <bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://10.1.242.146:61616" /> </bean> <bean id="helloQueue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg index="0" value="example.HelloQueue" /> </bean> <bean id="myQueueMessageListener" class="com.huey.hello.activemq.MyQueueMessageListener" /> <bean id="queueJmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory" /> <property name="destination" ref="helloQueue" /> <property name="messageListener" ref="myQueueMessageListener" /> </bean> </beans>
2. MyQueueMessageListener:
package com.huey.hello.activemq; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; public class MyQueueMessageListener implements MessageListener { public void onMessage(Message message) { try { if (message == null) { System.out.println("There are not any messages."); return; } if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; System.out.println("Receive a text message: " + textMessage.getText()); } else { System.out.println("Receive a non-text message."); } } catch (Exception e) { e.printStackTrace(); } } }
Working with Spring's JmsTemplate
Spring supports a handy abstraction, JmsTemplate, which allows you to hide some of the lower level JMS details when sending messages etc.One thing to bear in mind with JmsTemplate is that by default it will create a new connection, session, producer for each message sent - then close them all down again. This is very inefficient! It is done like this to work in EJB containers which tend to use a special ConnectionFactory which does pooling.
If you are not using a JCA container to manage your JMS connections, we recommend you use our pooling JMS connection provider, (org.apache.activemq.pool.PooledConnectionFactory) from the
activemq-poollibrary, which will pool the JMS resources to work efficiently with Spring's JmsTemplate or with EJBs.
e.g.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.huey.hello" /> <bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://10.1.242.146:61616" /> </bean> <bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> <property name="connectionFactory" ref="connectionFactory" /> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="jmsFactory" /> <property name="defaultDestination" ref="helloQueue" /> </bean> </beans>
The
PooledConnectionFactorysupports the pooling of Connection, Session and MessageProducer instances so it can be used with tools like Camel and Spring's JmsTemplate and MessagListenerContainer . Connections, sessions and producers are returned to a pool after use so that they can be reused later without having to undergo the cost of creating them again.
Note: while the
PooledConnectionFactorydoes allow the creation of a collection of active consumers, it does not 'pool' consumers. Pooling makes sense for connections, sessions and producers, which can be seldom-used resources, are expensive to create and can remain idle a minimal cost. Consumers, on the other hand, are usually just created at startup and left going, handling incoming messages as they come. When a consumer is complete, it's preferred to shut down it down rather than leave it idle and return it to a pool for later reuse: this is because, even if the consumer is idle, ActiveMQ will keep delivering messages to the consumer's prefetch buffer, where they'll get held up until the consumer is active again.
If you are creating a collection of consumers (for example, for multi-threaded message consumption), you should consider keeping a low prefetch value (e.g. 10 or 20), to ensure that all messages don't end up going to just one of the consumers.
Spring's MessagListenerContainer should be used for message consumption. This provides all the power of MDBs - efficient JMS consumption and pooling of the message listeners - but without requiring a full EJB container.
You can use the
activemq-pool
org.apache.activemq.pool.PooledConnectionFactoryfor efficient pooling of the connections and sessions for your collection of consumers, or you can use the Spring JMS
org.springframework.jms.connection.CachingConnectionFactoryto achieve the same effect.
相关文章推荐
- Eclipse启动报错 java was started but returned code=14
- [资料收集]Java问题解决
- Java将字节转换为十六进制代码分享
- java中数字类型转换
- 安装eclipse中文汉化包后无法打开eclipse
- Java知识四
- 从头认识java-17.4 详解同步(5)- 死锁
- JAVA菜鸟成长记——JNDI
- JAVA中去掉字符串空格的方法
- eclipse workspace libraries 配置文件地址
- 查看java进程
- eclipse各种问题汇总
- Myeclipse报错-Java compiler level does not match 完美解决方法
- 七张图解读Java多线程
- Windows JDK 环境变量配置
- Android Studio项目依赖Eclipse项目
- Java SE 学习 第二讲
- [转]Java中ArrayList和LinkedList区别
- 深入分析JavaWeb Item52 -- Spring注解Annotation
- @Override报错, 因为升级jdk项目出现java版本问题