用Spring發送和接受JMS消息的一個小例子

jopen 10年前發布 | 95K 次閱讀 Spring 消息系統

摘要 和通過直接使用JMS的API相比,大大簡化了代碼的編寫。

Spring提供的JmsTemplate對原生的JMS API進行了一層薄薄的封裝,使用起來非常的方便。

我使用的JMS消息代理插件是Apache的ActiveMQ,建議安裝最新版本,因為我之前安裝老版本,各種不兼容,各種bug,最新版的activemq-all-5.9.1.jar包里面已經有了slf4j.impl包,之前就是被這個坑了...把這個jar包加到lib目錄下面,就不會有各種ClassNotFound異常和類沖突的bug了。

下載ActiveMQ解壓之后運行bin下面的activemq.bat就可以運行了。你可以訪問http://127.0.0.1:8161/看看服務是否正常開啟

默認賬戶密碼是admin/admin

下面這個例子是一個郵局系統,包括前后臺兩個子系統,當前臺收到一封郵件的時候,它將這封郵件傳遞給后臺,同時發送一個JMS消息給后臺子系統,提醒新的郵件。

JMS有兩種消息通信模型:

    1)、point-to-point 

    2)、pub/sub

這里我們當然是用的第一種模型.

首先我們建立一個Mail類:

package com.apress.springrecipes.post;

public class Mail {
    private String mailId;
    private String country;
    private double weight;

    public Mail() {
    }

    public Mail(String mailId, String country, double weight) {
        this.mailId = mailId;
        this.country = country;
        this.weight = weight;
    }

    public String getMailId() {
        return mailId;
    }

    public void setMailId(String mailId) {
        this.mailId = mailId;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }
}

一個前臺子系統接口:

package com.apress.springrecipes.post;

public interface FrontDesk {
    public void sendMail(Mail mail);
}

和它的實現類:

package com.apress.springrecipes.post;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class FrontDeskImpl2 implements FrontDesk {
    @Autowired
    private JmsTemplate jmsTemplate;
    @Autowired
    private Destination destination;
    @Override
    public void sendMail(final Mail mail) {
        jmsTemplate.send(destination,new MessageCreator() {

            @Override
            public Message createMessage(Session session) throws JMSException {
                MapMessage message = session.createMapMessage();
                message.setString("mailId", mail.getMailId());
                message.setString("country", mail.getCountry());
                message.setDouble("weight", mail.getWeight());
                return message;
            }
        });
    }
}

一個后臺子系統的接口:

package com.apress.springrecipes.post;

public interface BackOffice {
    public Mail receiveMail();
}

和它的實現類:

package com.apress.springrecipes.post;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.JmsUtils;

public class BackOfficeImpl2 implements BackOffice {
    @Autowired
    private JmsTemplate jmsTemplate;
    @Autowired
    private Destination destination;

    @Override
    public Mail receiveMail() {
        MapMessage message = (MapMessage) jmsTemplate.receive(destination);
        try {
            if (message == null) {
                return null;
            }
            Mail mail = new Mail();
            mail.setMailId(message.getString("mailId"));
            mail.setCountry(message.getString("country"));
            mail.setWeight(message.getDouble("weight"));
            return mail;
        } catch (JMSException e) {
            throw JmsUtils.convertJmsAccessException(e);
        }
    }
}

前臺子系統的xml配置文件bean-front.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: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:annotation-config/>  

    <bean id="frontDesk"    
        class="com.apress.springrecipes.post.FrontDeskImpl2" />

    <bean id="connectionFactory"
        class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616"/>
    </bean>

    <bean id="destination"
        class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg value="mail.queue" />
    </bean>

    <bean id="jmsTemplate"
        class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
    </bean>

</beans>

后臺子系統的xml配置文件bean-back.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: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:annotation-config />    

    <bean id="backOffice"
        class="com.apress.springrecipes.post.BackOfficeImpl2" />

    <bean id="connectionFactory"
        class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616" />
    </bean>

    <bean id="destination"
        class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg value="mail.queue" />
    </bean>

    <bean id="jmsTemplate"
        class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="receiveTimeout" value="10000" />
    </bean>

</beans>

兩個測試類,一個是發消息,一個是接受消息。

package com.apress.springrecipes.post;

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

public class FrontDeskMain {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans-front.xml");
        FrontDesk frontDesk = (FrontDesk) context.getBean("frontDesk");
        frontDesk.sendMail(new Mail("1234","US",1.5));
    }
}

package com.apress.springrecipes.post;

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

public class BackOfficeMain {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans-back.xml");
        BackOffice backOffice = (BackOffice) context.getBean("backOffice");
        Mail mail = backOffice.receiveMail();
        System.out.println("Mail #" + mail.getMailId() + " received");
    }
}

運行FrontDeskMain之后,發送消息你可以簡單的通過訪問http://127.0.0.1:8161/admin/queueGraph.jsp和http://127.0.0.1:8161/admin/queues.jsp觀察發生的情況。再運行BackOfficeMain觀察這兩個頁面的變化。

 
來自:http://my.oschina.net/fengshuzi/blog/346303

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!