JMS与Sping

Posted slowdownthenrunfast

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JMS与Sping相关的知识,希望对你有一定的参考价值。

在Spring框架中使用JMS传递消息有两种方式:JMS template和message listener container,前者用于同步收发消息,后者用于异步收发消息。

1.       JMS template综述

使用JmsTemplate收发消息可以显著减少开发的精力投入。使用JmsTemplate时,不需要费心考虑连接到JMS provider(如ActiveMQ),建立JMS Session(如QueueSession),建立消息生产者(如QueueSender),甚至不用新建一个JMS消息(如TextMessage)。JmsTemplate能够自动将各种类型如String、Byte[]等转换为响应的JMS消息对象类型,当然也可以自己写Converter转换复杂的消息。

JmsTemplate常用的方法有send、convertAndSend、receive和convertAndReceive。

2.       详细步骤

下面通过一个例子详细讲解使用JmsTemplate同步收发消息。

(1)       环境

JMS1.1;apache-activemq-5.4.0;Spring-2.5.4;JDK-1.5;myeclipse7.5

(2)       源代码(Java Project)

i)                结构


ii)              源代码

.classpath:

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

<classpath>
	<classpathentry kind="src" path="src/main/java" />
	<classpathentry kind="src" path="src/main/resources" />
	<classpathentry exported="true" kind="con"
		path="org.eclipse.jdt.launching.JRE_CONTAINER" />
	<classpathentry exported="true" kind="lib" path="lib/jms-1.1.jar" />
	<classpathentry exported="true" kind="lib" path="lib/spring.jar" />
	<classpathentry exported="true" kind="lib"
		path="lib/activemq-all-5.4.0.jar" />
	<classpathentry kind="output" path="bin" />
</classpath>

jndi.properties:

java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url = tcp://localhost:61616
java.naming.security.principal=system
java.naming.security.credentials=manager
connectionFactoryNames = QueueCF
queue.queue1 = jms.queue1
app-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jms="http://www.springframework.org/schema/jms"
	xsi:schemaLocation="
       http://www.springframework.org/schema/beans spring-beans-2.0.xsd
            http://www.springframework.org/schema/jms
            http://www.springframework.org/schema/jms/spring-jms-2.5.xsd">

	<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
		<property name="environment">
			<props>
				<prop key="java.naming.factory.initial">
					org.apache.activemq.jndi.ActiveMQInitialContextFactory
				</prop>
				<prop key="java.naming.provider.url">tcp://localhost:61616</prop>
				<prop key="java.naming.security.principal">system</prop>
				<prop key="java.naming.security.credentials">manager</prop>
			</props>
		</property>
	</bean>

	<bean id="jndiQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiTemplate" ref="jndiTemplate" />
		<property name="jndiName" value="QueueCF" />
	</bean>

	<bean id="queueConnectionFactory"
		class="org.springframework.jms.connection.CachingConnectionFactory">
		<property name="targetConnectionFactory" ref="jndiQueueConnectionFactory" />
		<property name="sessionCacheSize" value="1" />
	</bean>

	<bean id="queueDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiTemplate" ref="jndiTemplate" />
		<property name="jndiName" value="queue1" />
	</bean>

	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="queueConnectionFactory" />
		<property name="defaultDestinationName" value="queue1" />
		<property name="pubSubDomain" value="false" />
	</bean>

	<bean id="jmsSender" class="com.jms.client.JMSSender">
		<property name="jmsTemplate" ref="jmsTemplate" />
		<property name="queueName" value="queue1" />
	</bean>

</beans>
JMSReceiverSync.java:

package com.tjl.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;

public class JMSReceiverSync 

	public static void main(String[] args) 

		try 
			ApplicationContext ctx = new ClassPathXmlApplicationContext(
					"app-context.xml");
			JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate");
			int counter = 0;
			while (counter < 10) 
				Object msg = jmsTemplate.receiveAndConvert();
				if (msg instanceof String) 
					System.out.println("Received: " + msg);
				
				counter++;
			
			System.exit(0);
		 catch (Exception up) 
			up.printStackTrace();
		
	


JMSSender.java:

package com.tjl.test;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class JMSSender 

	public void sendMessage() throws Exception 
		MessageCreator msg = new MessageCreator() 
			public Message createMessage(Session session) throws JMSException 
				TextMessage msg = session.createTextMessage("TEST 1");
				return msg;
			
		;

		jmsTemplate.send(queueName, msg);
		System.out.println("Message Sent...");
	

	public JmsTemplate jmsTemplate = null;
	public String queueName = null;

	public void setJmsTemplate(JmsTemplate jmsTemplate) 
		this.jmsTemplate = jmsTemplate;
	

	public void setQueueName(String queueName) 
		this.queueName = queueName;
	


JMSSenderApp.java:

package com.tjl.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class JMSSenderApp 

	public static void main(String[] args) 
		try 
			ApplicationContext ctx = new ClassPathXmlApplicationContext(
					"app-context.xml");
			JMSSender jmsSender = (JMSSender) ctx.getBean("jmsSender");
			jmsSender.sendMessage();
			System.exit(0);
		 catch (Exception exception) 
			exception.printStackTrace();
		

	


(3)       说明

可以看到,用JmsTemplate收发消息非常简单,因为JmsTemplate几乎帮我们做了大多数的工作,相关关系如下图所示(可结合app-context.xml理解):


3.       疑惑

明明用app-context.xml就包含所有的上下文信息了,可是删掉jndi.properties依然会出错。



以上是关于JMS与Sping的主要内容,如果未能解决你的问题,请参考以下文章

sping揭秘24Spring框架对JMS的集成(无环境版,以后学MQ的时候再隆重介绍)& 任务调度和线程池

Elasticsearch与Sping Data框架的集成

Apache CXF实战之二 集成Sping与Web容器

Sping 4 异常处理

JMS与ActiveMQ

ActiveMQ 与 JMS