activeMQ發送郵件小例子

  1. 先安裝apache-activemq-5.11.1 ,然後啓動activemq.bat

    QQ圖片20180507225240.png

  2. 啓動activeMQ的控制檯:http://localhost:8161/admin/,展示圖如下:

    QQ圖片20180507225519.png


解釋:Number Of Pending Messages  :等待消費的消息,這個是當前未出隊列的數量Number Of Consumers  :表示消費者數量Messages Enqueued 進入隊列的消息;( 這個數量只增不減,重啓acmq後會清零);Messages Dequeued  :出了隊列的消息  可以理解爲是消費這消費掉的數量 (重啓acmq後會清零)。


二,項目原碼的解析

1.消息消費者:

    mail.properties

mail.host=smtp.qq.com
mail.port=25
[email protected](消息發送方)
mail.password=郵箱的授權碼
mail.debug=true
mail.smtp.auth=true
mail.smtp.ssl.enable=true
[email protected](消息發送方,這個要與上面的要保持一直,不然會出錯)

 注:郵箱的授權碼的獲取:郵箱授權碼的獲取方法

 spring-mq.xml

<!-- 真正可以產生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="wusc.edu.demo.mqtest.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>

spring-mail.xml:

<!-- 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="defaultEncoding" value="UTF-8"></property>
		<property name="javaMailProperties">
			<props>
				 <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
                <!-- Debug模式 -->
                <prop key="mail.debug">${mail.debug}</prop>
                <!-- 使用SSL -->
                <prop key="mail.smtp.ssl.enable">${mail.smtp.ssl.enable}</prop>
                <!-- 配置MailSSLSocketFactory -->
                <prop key="mail.smtp.ssl.socketFactory">mailSSLSocketFactory</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>

郵件業務處理類

@Component("mailBiz")
public class MailBiz {

	@Autowired
	private JavaMailSender mailSender;// spring配置中定義
	@Autowired
	private SimpleMailMessage simpleMailMessage;// spring配置中定義
	@Autowired
	private ThreadPoolTaskExecutor threadPool;

	/**
	 * 發送模板郵件
	 * 
	 * @param mailParamTemp需要設置四個參數
	 *            templateName,toMail,subject,mapModel
	 * @throws Exception
	 * 
	 */
	public void mailSend(final MailParam mailParam) {
		threadPool.execute(new Runnable() {
			public void run() {
				try {
					simpleMailMessage.setFrom(simpleMailMessage.getFrom()); // 發送人,從配置文件中取得
					simpleMailMessage.setTo(mailParam.getTo()); // 接收人
					simpleMailMessage.setSubject(mailParam.getSubject());
					simpleMailMessage.setText(mailParam.getContent());
					mailSender.send(simpleMailMessage);
				} catch (MailException e) {
					throw e;
				}
			}
		});
	}
}

隊列監聽器 .ConsumerSessionAwareMessageListener

@Component
public class ConsumerSessionAwareMessageListener implements SessionAwareMessageListener<Message> {

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

	@Autowired
	private JmsTemplate activeMqJmsTemplate;
	@Autowired
	private Destination sessionAwareQueue;
	@Autowired
	private MailBiz bailBiz;

	public synchronized void onMessage(Message message, Session session) {
		try {
			ActiveMQTextMessage msg = (ActiveMQTextMessage) message;
			final String ms = msg.getText();
			log.info("==>receive message:" + ms);
			MailParam mailParam = JSONObject.parseObject(ms, MailParam.class);// 轉換成相應的對象
			if (mailParam == null) {
				return;
			}

			try {
				bailBiz.mailSend(mailParam);
			} catch (Exception e) {
				// 發送異常,重新放回隊列
//				activeMqJmsTemplate.send(sessionAwareQueue, new MessageCreator() {
//					public Message createMessage(Session session) throws JMSException {
//						return session.createTextMessage(ms);
//					}
//				});
				log.error("==>MailException:", e);
			}
		} catch (Exception e) {
			log.error("==>", e);
		}
	}
}

異常的處理邏輯現存問題,會出現死循環,所以註釋掉了

郵件參數封裝類 (MailParam)

public class MailParam {

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

	public MailParam() {
	}

	public MailParam(String to, String subject, String content) {
		this.to = to;
		this.subject = subject;
		this.content = 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;
	}
}

ActiveMQ測試啓動類  .

public class MQConsumer {
	private static final Log log = LogFactory.getLog(MQConsumer.class);

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

 項目結構圖如下:

QQ圖片20180507231351.png


②:消息生產者:

mq.properties

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

spring-mq.xml:

	<!-- 真正可以產生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>

ActiveMQ測試啓動類

public class MQProducerTest {
	private static final Log log = LogFactory.getLog(MQProducerTest.class);

	public static void main(String[] args) {
		try {
			ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/spring-context.xml");
			context.start();

			MQProducer mqProducer = (MQProducer) context.getBean("mqProducer");
			// 郵件發送
			MailParam mail = new MailParam();
			mail.setTo("你要接收的郵箱");
			mail.setSubject("ActiveMQ測試");
			mail.setContent("通過ActiveMQ異步發送郵件!");

			mqProducer.sendMessage(mail);

			context.stop();
		} catch (Exception e) {
			log.error("==>MQ context start error:", e);
			System.exit(0);
		} finally {
			log.info("===>System.exit");
			System.exit(0);
		}
	}
}

項目結構圖:

111.png

這樣就可以了。

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