您的位置:首页 > 编程语言 > Java开发

Spring 对JMS的支持

2014-03-06 10:01 176 查看
Spring提供了一个用于简化JMS API使用的抽象框架,用户利用Spring使用JMS可以不用关心connection factory,session等资源的管理.类似于对JDBC的抽象,Spring提供了一个
JmsTemplate类,抽象了操作JMS都必须做的公共步骤,留下了callback方法给用户去实现,如提供消息的真正内容等.


本文主要讲解一下怎么使用Spring来发送消息,接受消息和异步接受消息(MessageListener).

一,发送消息:

1,通过
JmsTemplate的
send方法和提供一个
MessageCreator的实现的最简单应用:


JAVA类(用配置文件中配置的默认的queue):


public class JMSsenderBean {

private JmsTemplate jmsTemplate;

public void simpleSend() {

this.jmsTemplate.send(new MessageCreator() {

public Message createMessage(Session session) throws JMSException {

return session.createTextMessage("hello queue world");

}

});

}


配置:(本例在weblogic上配置了JMS服务)


<beans>

<bean id="JMSsenderBean" class="com.test.spring.jms.JMSsenderBean">

<property name="jmsTemplate">

<ref local="jmsTemplate"></ref>

</property>

<property name="queue">

<ref local="destination1"></ref>

</property>

</bean>

<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">

<property name="jndiName">

<value>jms/jmsconf</value>

</property>

<property name="jndiTemplate">

<ref local="jndiTemplate"></ref>

</property>

</bean>

<bean id="destination1" class="org.springframework.jndi.JndiObjectFactoryBean">

<property name="jndiName">

<value>jms/jmsq1</value>

</property>

<property name="jndiTemplate">

<ref local="jndiTemplate"></ref>

</property>

</bean>

<bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">

<property name="jndiName">

<value>jms/jmsq</value>

</property>

<property name="jndiTemplate">

<ref local="jndiTemplate"></ref>

</property>

</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">

<property name="connectionFactory">

<ref local="connectionFactory" />

</property>

<property name="defaultDestination">

<ref local="destination" />

</property>

</bean>

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">

<property name="environment">

<props>

<prop key="java.naming.factory.initial">

weblogic.jndi.WLInitialContextFactory

</prop>

<prop key="java.naming.provider.url">

t3://localhost:7001

</prop>

<!--

<prop key="java.naming.security.authentication"> weblogic </prop>

<prop key="java.naming.security.credentials"> security </prop>

-->

</props>

</property>

</bean>

</beans>


2,
在发送的时候指定Queue:(配置同上)


public void withQSend() {

this.jmsTemplate.send(queue, new MessageCreator() {

public Message createMessage(Session session) throws JMSException {

return session.createTextMessage("hello queue world to jmsq1");

}

});

}


3,通过[code]JmsTemplate的
convertAndSend方法和提供一个MessageConverter
的实现来将传入的对象转成message:


public void convertAndSend(MsgObject object) {

this.jmsTemplate.setMessageConverter(new MyMessageConverter());

this.jmsTemplate.convertAndSend(object);

}

public class MyMessageConverter implements MessageConverter{

public Object fromMessage(Message message) throws JMSException, MessageConversionException {

TextMessage msg = (TextMessage)message;

MsgObject obj = new MsgObject();

obj.setName("from message");

return obj;

}

public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {

MsgObject obj = (MsgObject)object;

return session.createTextMessage("from Object MsgObject " + obj.getName() + "  " + obj.getAge());

}

}


4,实现 
SessionCallback,利用
[code]JmsTemplate的execute方法来对session进行操作,可以发送和接受消息.


public void sessionCbkSend() {

this.jmsTemplate.execute(new MySessionCallback(this.jmsTemplate));

}

public class MySessionCallback implements SessionCallback{

private JmsTemplate jmsTemplate;

public MySessionCallback(JmsTemplate jmsTemplate) {

this.jmsTemplate = jmsTemplate;

}

public Object doInJms(Session session) throws JMSException {

jmsTemplate.send(new MessageCreator() {

public Message createMessage(Session session) throws JMSException {

System.out.println("..............");

return session.createTextMessage("message from session back");

}

});

System.out.println("..............");

return null;

}

}


二,接受消息


public void receiveMsg() {

TextMessage msg = (TextMessage)this.jmsTemplate.receive();

try {

System.out.println(msg.getText());

} catch (JMSException e) {

e.printStackTrace();

}

}


三,异步接受消息:实现MessageListener,配置listenerContainer,默认情况下,Spring容器启动后,Listener就会启动.


public class ExampleListener implements MessageListener {

public void onMessage(Message message) {

if (message instanceof TextMessage) {

try {

System.out.println(((TextMessage) message).getText());

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

} catch (JMSException ex) {

throw new RuntimeException(ex);

}

} else {

throw new IllegalArgumentException("Message must be of type TextMessage");

}

}

}


配置


<bean id="messageListener" class="com.test.spring.jms.ExampleListener">

</bean>

<bean id="jmsContainer"

class="org.springframework.jms.listener.DefaultMessageListenerContainer">

<property name="connectionFactory" ref="connectionFactory" />

<property name="destination" ref="destination" />

<property name="messageListener" ref="messageListener" />

</bean>


通过listenerContainer的stop和shutdown方法停止服务.


jmsContainer.stop();

jmsContainer.shutdown();

对listener的事务管理:

如果是本地事务,只需要设置listenerContainer的sessionTransacted就可以了.

<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">

...

<property name="sessionTransacted" value="true"/>

</bean>
如果在onMessage中还有对其他资源,如数据库的操作,需要使用JTA来控制全局事务.


<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>

<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">

...

<property name="transactionManager" ref="transactionManager" />

</bean>


原文链接:http://blog.csdn.net/kkdelta/article/details/5604218
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: