JMS与Spring的整合实例(基于Apache ActiveMQ)JMS的介绍

来源:互联网 发布:mac怎么卸载插件 编辑:程序博客网 时间:2024/05/22 01:49

什么是JMS?

jms即Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。

 

JMS的优势

当前,CORBA、DCOM、RMI等RPC中间件技术已广泛应用于各个领域。但是面对规模和复杂度都越来越高的分布式系统,这些技术也显示出其局限性:

(1)同步通信:客户发出调用后,必须等待服务对象完成处理并返回结果后才能继续执行;

(2)客户和服务对象的生命周期紧密耦合:客户进程和服务对象进程 都必须正常运行;如果由于服务对象崩溃或者网络故障导致客户的请求不可达,客户会接收到异常;

(3)点对点通信:客户的一次调用只发送给某个单独的目标对 象。
面向消息的中间件(Message Oriented Middleware,MOM)较好的解决了以上问题。发送者将消息发送给消息服务器,消息服务器将消息存放在若干队列中,在合适的时候再将消息转发给接 收者。这种模式下,发送和接收是异步的,发送者无需等待;二者的生命周期未必相同:发送消息的时候接收者不一定运行,接收消息的时候发送者也不一定运行; 一对多通信:对于一个消息可以有多个接收者。
已有的MOM系统包括IBM的MQSeries、Microsoft的MSMQ和BEA的MessageQ等。由于没有一个通用的标准,这些系统很难实现 互操作和无缝连接。

Java Message Service(JMS)是SUN提出的旨在统一各种MOM系统接口的规范,它包含点对点(Point to Point,PTP)和发布/订阅(Publish/Subscribe,pub/sub)两种消息模型,提供可靠消息传输、事务和消息过滤等机制。JMS并不是一个产品而是一个规范,JMS的出现是一个巨大变革。

满足大量应用的需求,运行于多种硬件和操作系统平台,支持分布式计算,支持标准接口和协议。开发人员通过调用中间件提供的大量API,实现异构环境的通信,从而屏蔽异构系统中复杂的操作系统和网络协议。

由于标准接口对于可移植性和标准协议对于互操作性的重要性,中间件已成为许多标准化工作的主要部分。分布式应用软件借助中间件可以在不同的技术之间共享资源。

总的来说,中间件屏蔽了底层操作系统的复杂性,使程序开发人员面对一个简单而统一的开发环境,减少了程序设计的复杂性,将注意力集中与自己的业务上,不必再为程序在不同软件系统上的移植而重复工作,从而大大减少了技术上的负担。

 

Take in Action

在理解了什么是JMS后,在实践阶段Dreamforce会向你介绍在Spring中整合JMS,同时结合Apache ActiveMQ来实现一个模拟聊天器的功能。

来务场景: A在输入端输入相应消息,消息会异步发送到ActiveMQ,B端会监听这个队列,如果有新数据入队,则接收此消息。

根据本实例,你可以通过简单的修改实现双人或多人自由聊天功能。

在本例中,使用Apache 的ActiveMQ来作为JMS中间件,这是一款相当成熟且开源的产品,得到了许多业内人士的好评。

开发采用Spirng Maven集成开发环境,所有的Jar包通过Maven进行管理 , 如果对Spring Maven集成开发环境配置不熟悉的,可以先看这里:http://dreamforce.me/archives/87

新建一个ApplicationContext-JMS.xml

 

<!-- 定义JMS连接工厂 -->

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

        <property name="brokerURL" value="tcp://服务器IP:61616" />

</bean>

<!-- 定义JMS Template -->

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

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

    </bean>

<!--     定义<<发布>>消息的目的地 -->

<bean id="publisherDestination" class="org.apache.activemq.command.ActiveMQQueue">

        <constructor-arg index="0" value="bekiz_publisher" />

</bean>

<!--     定义<<接收>>消息的目的地 -->

<bean id="receiverDestination" class="org.apache.activemq.command.ActiveMQQueue" >

        <constructor-arg index="0" value="bekiz_receiver" />

</bean>

<!-- 定义一个JMS话题   暂时没用上 -->

<bean id="jmsTopic" class="org.apache.activemq.command.ActiveMQTopic" >

        <constructor-arg value="STOCKS.Dreamforce.jms"  index="0" />

</bean>

<!-- 定义消费者(接收端) -->

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

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

        <property name="destination" ref="receiverDestination" />     <!-- 注入监听队列 -->

        <property name="messageListener" ><bean  class="com.bekiz.jms.TextListener"  /></property>   <!-- 注入监听 -->

</bean>

<!-- 定义发布者 -->

<bean id="publisher" class="com.bekiz.jms.Publisher">

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

        <property name="destinations" ref="publisherDestination" />

 </bean>

</beans>

发布者的类

public class Publisher {


private  JmsTemplate  jmsTemplate ;

private Destination  destinations;

public void setDestinations(Destination destinations) {

this.destinations = destinations;

}

public void setJmsTemplate(JmsTemplate jmsTemplate) {

this.jmsTemplate = jmsTemplate;

}

// 发布

public  void publisher(){

while (true){

jmsTemplate.send(destinations,new MessageCreator(){

@Override

public MapMessage createMessage(Session session) throws JMSException {

MapMessage  message = session.createMapMessage();

Scanner  cin = new Scanner(System.in);

String msg =cin.nextLine();

 

String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());

message.setString("id", "ming");

message.setString("message", msg);

message.setString("date", date);

return message;

}

});

}

}}

 监听类

public class TextListener implements MessageListener {


@Override
public void onMessage(Message message) {

ActiveMQMapMessage msg = null;
if(message  instanceof  ActiveMQMapMessage){
msg = (ActiveMQMapMessage) message;
try {
String receiverPerson=msg.getString("id");
String receiverMessage=msg.getString("message");
String  receiverDate= msg.getString("date");
System.out.println("时间:"+receiverDate+"\t"+receiverPerson+"\t"+receiverMessage);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
JUnit 测试类
public class JunitJMS {

private  static Publisher  publisher;
private static DefaultMessageListenerContainer receiver;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
ApplicationContext  context = new ClassPathXmlApplicationContext("Application.xml");
publisher=(Publisher) context.getBean("publisher");
receiver=(DefaultMessageListenerContainer) context.getBean("receiver");
}
@Test
public void test() {
publisher.publisher();
receiver.start();
}

}

 

原创粉丝点击