深入淺出JMS(六)--ActiveMQ實現消息隊列發送郵件

  1. 新建yncp.mq.mailservice工程,編寫以下類

Mail類:

 package com.yncp.mq.entity;

 /***
  * 郵件實體
  * @author Administrator
  *
  */
public class Mail {

    /** 發件人 **/
    private String from;
    /** 收件人 **/
    private String to;
    /** 主題 **/
    private String subject;
    /** 郵件內容 **/
    private String content;


    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}
消費者session監聽類:

package com.yncp.mq.listener;

import javax.jms.Message;
import javax.jms.Session;

import org.apache.activemq.command.ActiveMQTextMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.listener.SessionAwareMessageListener;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.yncp.mq.entity.Mail;
import com.yncp.mq.mail.MailTest;

@Component
public class ConsumerSessionAwareMessageListener implements
        SessionAwareMessageListener<Message> {

    private static final Log log = LogFactory
            .getLog(ConsumerSessionAwareMessageListener.class);

    @Autowired
    private MailTest mailTest;

    public synchronized void onMessage(Message message, Session session) {
        try {
            ActiveMQTextMessage msg = (ActiveMQTextMessage) message;
            final String ms = msg.getText();
            log.info("==>receive message:" + ms);
            Mail mail = JSONObject.parseObject(ms, Mail.class);
            if (mail == null) {
                return;
            }
            try {
                mailTest.sendMail(mail);
            } catch (Exception e) {             
                log.error("==>MailException:", e);
            }
        } catch (Exception e) {
            log.error("==>", e);
        }
    }
}

發送郵件的模板類:

package com.yncp.mq.mail;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import com.yncp.mq.entity.Mail;

@Component("mailTest")
public class MailTest {

    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private SimpleMailMessage simpleMailMessage;
    @Autowired
    private ThreadPoolTaskExecutor threadPool;

    /**
     * 發送郵件
     * @param mail
     */
    public void sendMail(final Mail mail) {
        threadPool.execute(new Runnable() {
            public void run() {
                try {
                    simpleMailMessage.setFrom(simpleMailMessage.getFrom());
                    simpleMailMessage.setTo(mail.getTo());
                    simpleMailMessage.setSubject(mail.getSubject());
                    simpleMailMessage.setText(mail.getContent());
                    mailSender.send(simpleMailMessage);
                } catch (MailException e) {
                    throw e;
                }
            }
        });
    }

}

spring-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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
           http://www.springframework.org/schema/aop   
           http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
           http://www.springframework.org/schema/tx  
           http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.2.xsd"
    default-autowire="byName" default-lazy-init="false">     
    <!-- 採用註釋的方式配置bean -->
    <context:annotation-config />
    <!-- 配置要掃描的包 -->
    <context:component-scan base-package="com.yncp.mq" />
    <!-- 讀入配置屬性文件 -->
    <context:property-placeholder location="classpath:mq.properties,classpath:mail.properties" />

    <aop:aspectj-autoproxy proxy-target-class="true" />     
    <import resource="spring-mq.xml" />
    <import resource="spring-mail.xml" />

</beans>

spring-mail.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
       http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd">

    <!-- Spring提供的發送電子郵件的高級抽象類 -->
        <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">  
        <property name="host" value="${mail.host}" />  
        <property name="username" value="${mail.username}" />  
        <property name="password" value="${mail.password}" />  
        <property name="port" value="${mail.port}" />  
        <property name="javaMailProperties">  
            <props>  
                <prop key="mail.smtp.timeout">${mail.smtp.timeout}</prop>  
                <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>  
                <prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable}</prop>  
                <prop key="mail.smtp.socketFactory.port">${mail.port}</prop>  
                <prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>  
                <prop key="mail.smtp.socketFactory.fallback">false</prop>  
            </props>  
        </property>  
    </bean>  

    <bean id="simpleMailMessage" class="org.springframework.mail.SimpleMailMessage">
        <property name="from">
            <value>${mail.default.from}</value>
        </property>
    </bean>

    <!-- 配置線程池 -->
    <bean id="threadPool" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 線程池維護線程的最少數量 -->
        <property name="corePoolSize" value="5" />
        <!-- 線程池維護線程所允許的空閒時間 -->
        <property name="keepAliveSeconds" value="30000" />
        <!-- 線程池維護線程的最大數量 -->
        <property name="maxPoolSize" value="50" />
        <!-- 線程池所使用的緩衝隊列 -->
        <property name="queueCapacity" value="100" />
    </bean>

</beans>

spring-mq.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
           http://www.springframework.org/schema/aop   
           http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
           http://www.springframework.org/schema/tx  
           http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.2.xsd"
    default-autowire="byName" default-lazy-init="false">

    <!-- 真正可以產生Connection的ConnectionFactory,由對應的 JMS服務廠商提供 -->
    <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <!-- ActiveMQ服務地址 -->
        <property name="brokerURL" value="${mq.brokerURL}" />
        <property name="userName" value="${mq.userName}"></property>
        <property name="password" value="${mq.password}"></property> 
    </bean>

    <!-- 
        ActiveMQ爲我們提供了一個PooledConnectionFactory,通過往裏面注入一個ActiveMQConnectionFactory
        可以用來將Connection、Session和MessageProducer池化,這樣可以大大的減少我們的資源消耗。
        要依賴於 activemq-pool包
     -->
    <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
        <property name="connectionFactory" ref="targetConnectionFactory" />
        <property name="maxConnections" value="${mq.pool.maxConnections}" />
    </bean>

    <!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory -->
    <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
        <!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory -->
        <property name="targetConnectionFactory" ref="pooledConnectionFactory" />
    </bean>

    <!-- Spring提供的JMS工具類,它可以進行消息發送、接收等 -->

    <!-- 隊列模板 -->
    <bean id="activeMqJmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
        <!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory對象 -->  
        <property name="connectionFactory" ref="connectionFactory"/>  
        <property name="defaultDestinationName" value="${queueName}"></property>
    </bean> 

    <!--這個是sessionAwareQueue目的地 -->
    <bean id="sessionAwareQueue" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg>
            <value>${queueName}</value>
        </constructor-arg>
    </bean>

    <!-- 可以獲取session的MessageListener -->
    <bean id="consumerSessionAwareMessageListener" class="com.yncp.mq.listener.ConsumerSessionAwareMessageListener"></bean>

    <bean id="sessionAwareListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destination" ref="sessionAwareQueue" />
        <property name="messageListener" ref="consumerSessionAwareMessageListener" />
    </bean>

</beans>

mail.properties屬性:

mail.host=smtp.qq.com
mail.port=465
mail.username= //開通了smtp服務的QQ郵箱
mail.password=//授權碼
mail.smtp.auth=true
mail.smtp.timeout=30000
mail.smtp.starttls.enable=true
[email protected]
[email protected]

mq.properties屬性配置

mq.brokerURL=tcp\://127.0.0.1\:61616
mq.userName=admin
mq.password=admin
mq.pool.maxConnections=10
#queueName
queueName=mq.maintest

測試類:

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MQMailTest {

    public static void main(String[] args) {
        try {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                    "classpath:spring-context.xml");
            context.start();
        } catch (Exception e) {
            System.exit(0);
        }
    }
}

新建 yncp.mq.mailclient工程。實現發送郵件。
MQProducer類

package com.yncp.mq.client;

import javax.jms.JMSException;
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;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.yncp.mq.entity.Mail;

@Service("mqProducer")
public class MQProducer {

    @Autowired
    private JmsTemplate activeMqJmsTemplate;

    /**
     * 發送消息.
     * 
     * @param mail
     */
    public void sendMessage(final Mail mail) {
        activeMqJmsTemplate.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(JSONObject.toJSONString(mail));
            }
        });

    }

}

MQClientTest測試

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.yncp.mq.client.MQProducer;
import com.yncp.mq.entity.Mail;


public class MQClientTest {
    public static void main(String[] args) {
        try {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-context.xml");
            context.start();
            MQProducer mqProducer = (MQProducer) context.getBean("mqProducer");
            // 發送郵件
            Mail mail = new Mail ();
            mail.setTo("[email protected]");//郵件接收方
            mail.setSubject("hello");//郵件標題
            mail.setContent("hello,this is first email");//郵件內容
            mqProducer.sendMessage(mail);
            context.stop();
        } catch (Exception e) { 
            System.exit(0);
        } finally { 
            System.exit(0);
        }
    }
}

spring-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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
           http://www.springframework.org/schema/aop   
           http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
           http://www.springframework.org/schema/tx  
           http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.2.xsd"
    default-autowire="byName" default-lazy-init="false">

    <!-- 採用註釋的方式配置bean -->
    <context:annotation-config />

    <!-- 配置要掃描的包 -->
    <context:component-scan base-package="com.yncp.mq" />

    <!-- 讀入配置屬性文件 -->
    <context:property-placeholder location="classpath:mq.properties" />

    <!-- proxy-target-class默認"false",更改爲"ture"使用CGLib動態代理 -->
    <aop:aspectj-autoproxy proxy-target-class="true" /> 

    <import resource="spring-mq.xml" />
</beans>

spring-mq.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
           http://www.springframework.org/schema/aop   
           http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
           http://www.springframework.org/schema/tx  
           http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.2.xsd"
    default-autowire="byName" default-lazy-init="false">

    <!-- 真正可以產生Connection的ConnectionFactory,由對應的 JMS服務廠商提供 -->
    <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <!-- ActiveMQ服務地址 -->
        <property name="brokerURL" value="${mq.brokerURL}" />
        <property name="userName" value="${mq.userName}"></property>
        <property name="password" value="${mq.password}"></property> 
    </bean>

    <!-- 
        ActiveMQ爲我們提供了一個PooledConnectionFactory,通過往裏面注入一個ActiveMQConnectionFactory
        可以用來將Connection、Session和MessageProducer池化,這樣可以大大的減少我們的資源消耗。
        要依賴於 activemq-pool包
     -->
    <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
        <property name="connectionFactory" ref="targetConnectionFactory" />
        <property name="maxConnections" value="${mq.pool.maxConnections}" />
    </bean>

    <!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory -->
    <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
        <!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory -->
        <property name="targetConnectionFactory" ref="pooledConnectionFactory" />
    </bean>

    <!-- Spring提供的JMS工具類,它可以進行消息發送、接收等 -->

    <!-- 隊列模板 -->
    <bean id="activeMqJmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
        <!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory對象 -->  
        <property name="connectionFactory" ref="connectionFactory"/>  
        <property name="defaultDestinationName" value="${queueName}"></property>
    </bean> 

</beans>

運行MQClientTest就可以發送郵件啦。

當我們服務器端沒有運行時,此時運行MQClientTest。
我們會發現此時的activemq有一個消息掛起。
這裏寫圖片描述
當啓動服務器時,消息會發送到服務器端,服務器端接受消息後會發送郵件。

這裏寫圖片描述


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章