spring jms

1.概述:Spring提供了一个用于简化JMSAPI使用的抽象框架,并且对用户屏蔽了JMSAPI中1.0.2和1.1版本的差异。

JMS的功能大致上分为两块,叫做消息制造和消息消耗。JmsTemplate用于制造消息和同步消息接收。我们今天就用JmsTemplate实现同步的消息接受。

使用JMS发(接)消息的步骤:

1)创建连接工厂

2)使用连接工厂创建连接

3)使用连接创建会话

4)获取一个目的地

5)使用会话和目的地创建消息生产者(消息消费者)

6)使用连接创建一个需要发送的消息类型实例

7)使用连接的一个队列发送器或主题公布器,使用发送器或者主题器发送消息(接受消息)

spring中的JmsTemplate实现了对jms的一些封装,内部提供了很多的方法,我们只需要实现定义的回调接口即可。JmsTemplate继承自JmsAccessor,在JmsAccessor中有ConnectionFactory的定义,而JmsTemplate本身的构造方法也有对ConnectionFactory的封装:

Java代码

publicJmsTemplate(ConnectionFactoryconnectionFactory){

this();

setConnectionFactory(connectionFactory);

afterPropertiesSet();

}

所以,我们有两种方式注入ConnectionFactory,本文我们采用构造方法的方式。

spring_jms.xml

Java代码

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!--这里我们用构造方法注入connectionFactory-->

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

<constructor-argref="connectionFactory"></constructor-arg>

</bean>

<!--使用activemq中的连接工厂,提供一个brokerUrl,这里表示本地-->

<beanid="connectionFactory"class="org.apache.activemq.ActiveMQConnectionFactory">

<propertyname="brokerURL"value="vm://localhost"/>

</bean>

<!--使用activemq中的点对点消息模型,随意指定一个地址-->

<beanid="destination"class="org.apache.activemq.command.ActiveMQQueue">

<constructor-argvalue="test/queue"/>

</bean>

</beans>

MessageCreator回调接口通过JmsTemplate中调用代码提供的Session来创建一条消息。

看一下MessageCreator接口:

Java代码

publicinterfaceMessageCreator{

MessagecreateMessage(Sessionsession)throwsJMSException;

}

那么,我们来实现发送和接受消息DummyJms类

Java代码

publicclassDummyJms{

publicstaticvoidmain(String[]args)throwsException{

ApplicationContextcontext=newClassPathXmlApplicationContext("spring.xml");

JmsTemplatejmsTemplate=(JmsTemplate)context.getBean("jmsTemplate");

Destinationdestination=(Destination)context.getBean("destination");

jmsTemplate.send(destination,newMessageCreator(){

publicMessagecreateMessage(Sessionsession)

throwsJMSException{

returnsession.createTextMessage("sendmessage");

}

});

TextMessagemsg=(TextMessage)jmsTemplate.receive(destination);

System.out.println("receivemessage="+msg.getText());

}

}

输出结果:

receivemessage=sendmessage

可是我们并没有看到的像前文描述的那那些创建消息生产者,消息消费者的一些东西。继续分析,我们可以看一下,

jmsTemplate.send(Destinationdestination,MessageCreatormessageCreator)这里到底做了什么,可以让我们不费吹灰之力,就可以实现消息的发送。JmsTemplate源代码:

Java代码

publicvoidsend(finalDestinationdestination,finalMessageCreatormessageCreator)throwsJmsException{

execute(newSessionCallback<Object>(){

publicObjectdoInJms(Sessionsession)throwsJMSException{

doSend(session,destination,messageCreator);

returnnull;

}

},false);

}

JmsTemplate实现了JmsOperations接口,在JmsOperations里有

Java代码

<T>Texecute(SessionCallback<T>action)throwsJmsException;

的定义。

那么这个SessionCallback接口是什么呢?它也为用户提供了JMSsession。

Java代码

publicinterfaceSessionCallback<T>{

TdoInJms(Sessionsession)throwsJMSException;

}

继续往下看。doSend方法:

Java代码

protectedvoiddoSend(Sessionsession,Destinationdestination,MessageCreatormessageCreator)

throwsJMSException{

Assert.notNull(messageCreator,"MessageCreatormustnotbenull");

MessageProducerproducer=createProducer(session,destination);

try{

Messagemessage=messageCreator.createMessage(session);

if(logger.isDebugEnabled()){

logger.debug("Sendingcreatedmessage:"+message);

}

doSend(producer,message);

//Checkcommit-avoidcommitcallwithinaJTAtransaction.

if(session.getTransacted()&&isSessionLocallyTransacted(session)){

//Transactedsessioncreatedbythistemplate->commit.

JmsUtils.commitIfNecessary(session);

}

}

finally{

JmsUtils.closeMessageProducer(producer);

}

}

createProducer()方法又调用了doCreateProducer(),实际的消息生产者在这里。

Java代码

protectedMessageProducerdoCreateProducer(Sessionsession,Destinationdestination)throwsJMSException{

returnsession.createProducer(destination);

}

在这里,我们看到了,spring创建了消息的发送者,关闭连接的一些操作。到这里,大家就明白了,spring内部处理Jms消息的过程了吧(消息的接受也是一样)。

相关推荐