Spring學(xué)習(xí)筆記3之消息隊(duì)列(rabbitmq)發(fā)送郵件功能
rabbitmq簡(jiǎn)介:
MQ全稱為Message Queue, 消息隊(duì)列(MQ)是一種應(yīng)用程序?qū)?yīng)用程序的通信方法。應(yīng)用程序通過(guò)讀寫(xiě)出入隊(duì)列的消息(針對(duì)應(yīng)用程序的數(shù)據(jù))來(lái)通信,而無(wú)需專用連接來(lái)鏈接它們。消息傳遞指的是程序之間通過(guò)在消息中發(fā)送數(shù)據(jù)進(jìn)行通信,而不是通過(guò)直接調(diào)用彼此來(lái)通信,直接調(diào)用通常是用于諸如遠(yuǎn)程過(guò)程調(diào)用的技術(shù)。排隊(duì)指的是應(yīng)用程序通過(guò) 隊(duì)列來(lái)通信。隊(duì)列的使用除去了接收和發(fā)送應(yīng)用程序同時(shí)執(zhí)行的要求。其中較為成熟的MQ產(chǎn)品有IBM WEBSPHERE MQ。
本節(jié)的內(nèi)容是用戶注冊(cè)時(shí),將郵箱地址先存入rabbitmq隊(duì)列,之后返回給用戶注冊(cè)成功;之后消息隊(duì)列的接收者從隊(duì)列中獲取消息,發(fā)送郵件給用戶。
一、RabbitMQ介紹
如果之前對(duì)rabbitmq不了解,推薦先看一下RabbitMQ Quick(快速手冊(cè))。
1、rabbitmq在mac上的安裝。
2、rabbitmq簡(jiǎn)單介紹。

生產(chǎn)者: 負(fù)責(zé)發(fā)送消息到Exchange。
Exchange: 按照一定的策略,負(fù)責(zé)將消息存入到指定的隊(duì)列。
隊(duì)列queue: 負(fù)責(zé)保存消息。
消費(fèi)者: 負(fù)責(zé)從隊(duì)列中提取消息。
binding: 負(fù)責(zé)Exchange和隊(duì)列的關(guān)聯(lián)映射,Exchange和queue是多對(duì)多的關(guān)系。
二、RabbitMQ在Spring中的實(shí)現(xiàn)
1、引入依賴包。
<dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-amqp</artifactId> <version>1.6.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-rabbit</artifactId> <version>1.6.0.RELEASE</version> </dependency>
2、rabbitmq配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/rabbit"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--1、配置連接工廠, 如果不配置host, port, username, passowrd, 則按默認(rèn)值localhost:5672, guest/guest-->
<!--<connection-factory id="connectionFactory" />-->
<connection-factory id="connectionFactory"
host="localhost"
port="5672"
username="everSeeker"
password="333" />
<!--2、配置隊(duì)列queue, Exchange, 以及將他們結(jié)合在一起的binding-->
<!--在queue以及exchange中, 有一個(gè)重要的屬性durable, 默認(rèn)為true, 可以防止宕機(jī)后數(shù)據(jù)丟失。-->
<!--在listener-container中, 有acknowledge屬性, 默認(rèn)為auto, 即消費(fèi)者成功處理消息后必須有個(gè)應(yīng)答, 如果消費(fèi)者程序發(fā)生異?;蛘咤礄C(jī), 消息會(huì)被重新放回隊(duì)列-->
<admin connection-factory="connectionFactory" />
<queue id="userAlertEmailQueue" name="user.alerts.email" durable="true" />
<queue id="userAlertCellphoneQueue" name="user.alerts.cellphone" /> <!--durable默認(rèn)為true-->
<!--標(biāo)準(zhǔn)的AMQP Exchange有4種: Direct, Topic, Headers, Fanout, 根據(jù)實(shí)際需要選擇。-->
<!--Direct: 如果消息的routing key與bingding的routing key直接匹配的話, 消息將會(huì)路由到該隊(duì)列上。-->
<!--Topic: 如果消息的routing key與bingding的routing key符合通配符匹配的話, 消息將會(huì)路由到該隊(duì)列上。-->
<!--Headers: 如果消息參數(shù)表中的頭信息和值都與binding參數(shù)表中相匹配, 消息將會(huì)路由到該隊(duì)列上。-->
<!--Fanout: 不管消息的routing key和參數(shù)表的頭信息/值是什么, 消息將會(huì)路由到該隊(duì)列上。-->
<direct-exchange name="user.alert.email.exchange" durable="true">
<bindings>
<binding queue="user.alerts.email" /> <!--默認(rèn)的routing key與隊(duì)列的名稱相同-->
</bindings>
</direct-exchange>
<direct-exchange name="user.alert.cellphone.exchange">
<bindings>
<binding queue="user.alerts.cellphone" />
</bindings>
</direct-exchange>
<!--3、配置RabbitTemplate發(fā)送消息-->
<template id="rabbitTemplate"
connection-factory="connectionFactory" />
<!--4、配置監(jiān)聽(tīng)器容器和監(jiān)聽(tīng)器來(lái)接收消息-->
<beans:bean id="userListener" class="com.everSeeker.alerts.UserAlertHandler" />
<listener-container connection-factory="connectionFactory" acknowledge="auto">
<listener ref="userListener"
method="handleUserAlertToEmail"
queues="userAlertEmailQueue" />
<listener ref="userListener"
method="handleUserAlertToCellphone"
queues="userAlertCellphoneQueue" />
</listener-container>
</beans:beans>
如果配置connection-factory時(shí),采用默認(rèn)的guest/guest賬號(hào)密碼時(shí),有可能會(huì)出現(xiàn)org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.的錯(cuò)誤提示,解決辦法是新建一個(gè)管理員權(quán)限的用戶,并允許訪問(wèn)虛擬主機(jī)。
步驟如下:
1、打開(kāi)http://localhost:15672/
2、Admin ——> Users, 新建用戶,administrator權(quán)限。
3、Virtual Hosts,設(shè)置新建用戶允許訪問(wèn)。
3、生產(chǎn)者發(fā)送消息到exchange。
@Service("userAlertService")
public class UserAlertServiceImpl implements UserAlertService {
private RabbitTemplate rabbit;
@Autowired
public UserAlertServiceImpl(RabbitTemplate rabbit) {
this.rabbit = rabbit;
}
public void sendUserAlertToEmail(User user) {
//convertAndSend(String exchange, String routingKey, Object object), 將對(duì)象object封裝成Message對(duì)象后, 發(fā)送給exchange
rabbit.convertAndSend("user.alert.email.exchange", "user.alerts.email", user);
}
}
4、配置消費(fèi)者來(lái)接收消息。
public class UserAlertHandler {
public void handleUserAlertToEmail(User user) {
System.out.println(user);
}
三、通過(guò)javax.mail來(lái)發(fā)送郵件
1、引入依賴包。
<dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency>
2、配置郵件服務(wù)器信息。
@Bean
public MailSender mailSender(Environment env) {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
//如果為普通郵箱, 非ssl認(rèn)證等, 比如163郵箱
mailSender.setHost(env.getProperty("mailserver.host"));
mailSender.setPort(Integer.parseInt(env.getProperty("mailserver.port")));
mailSender.setUsername(env.getProperty("mailserver.username"));
mailSender.setPassword(env.getProperty("mailserver.password"));
mailSender.setDefaultEncoding("utf-8");
//如果郵件服務(wù)器采用了ssl認(rèn)證, 增加以下配置, 比如gmail郵箱, qq郵箱
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.port", "465");
mailSender.setJavaMailProperties(props);
return mailSender;
}
3、發(fā)送郵件。
@Component("userMailService")
public class UserMailServiceImpl implements UserMailService {
private MailSender mailSender;
@Autowired
public UserMailServiceImpl(MailSender mailSender) {
this.mailSender = mailSender;
}
public void sendSimpleUserMail(String to, User user) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("xxxxxxxx@qq.com");
message.setTo(to);
message.setSubject(user.getUsername() + "信息確認(rèn)");
message.setText(user.toString());
mailSender.send(message);
}
}
4、消費(fèi)者調(diào)用發(fā)送郵件方法即可。
1、參考文獻(xiàn):Spring實(shí)戰(zhàn)(第4版)。
2、完整代碼在github,地址:https://github.com/everseeker0307/register。
以上所述是小編給大家介紹的Spring學(xué)習(xí)筆記3之消息隊(duì)列(rabbitmq)發(fā)送郵件功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- SpringBoot使用RabbitMQ延時(shí)隊(duì)列(小白必備)
- SpringBoot集成RabbitMQ的方法(死信隊(duì)列)
- springboot實(shí)現(xiàn)rabbitmq的隊(duì)列初始化和綁定
- Spring Boot與RabbitMQ結(jié)合實(shí)現(xiàn)延遲隊(duì)列的示例
- 消息隊(duì)列 RabbitMQ 與 Spring 整合使用的實(shí)例代碼
- rabbitmq結(jié)合spring實(shí)現(xiàn)消息隊(duì)列優(yōu)先級(jí)的方法
- Spring項(xiàng)目集成RabbitMQ及自動(dòng)創(chuàng)建隊(duì)列
相關(guān)文章
非常全面的Java?SpringBoot點(diǎn)贊功能實(shí)現(xiàn)
但是這些功能再項(xiàng)目中是高頻出現(xiàn)的,如果直接操作數(shù)據(jù)庫(kù)的話,對(duì)數(shù)據(jù)庫(kù)壓力太大。那遇到這個(gè)問(wèn)題怎么解決?這篇文章主要給大家介紹了關(guān)于Java?SpringBoot點(diǎn)贊功能實(shí)現(xiàn)?的相關(guān)資料,需要的朋友可以參考下2022-01-01
Spring?Boot使用線程池處理上萬(wàn)條數(shù)據(jù)插入功能
這篇文章主要介紹了Spring?Boot使用線程池處理上萬(wàn)條數(shù)據(jù)插入功能,使用步驟是先創(chuàng)建一個(gè)線程池的配置,讓Spring Boot加載,用來(lái)定義如何創(chuàng)建一個(gè)ThreadPoolTaskExecutor,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-08-08
Java實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問(wèn)題與讀者寫(xiě)者問(wèn)題詳解
這篇文章主要介紹了Java實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問(wèn)題與讀者寫(xiě)者問(wèn)題詳解,小編覺(jué)得挺不錯(cuò)的,這里分享給大家,供需要的親朋好友參考。2017-11-11
Java工具之ja-netfilter?2022.1?配置教程
這篇文章主要介紹了Java工具之ja-netfilter?2022.1?配置教程,本防火墻基于javaagent,所以目前只有基于java的程序能夠使用,需要的朋友可以參考下2022-04-04
SpringBoot的@ControllerAdvice處理全局異常詳解
這篇文章主要介紹了SpringBoot的@ControllerAdvice處理全局異常詳解,但有時(shí)卻往往會(huì)產(chǎn)生一些bug,這時(shí)候就破壞了返回?cái)?shù)據(jù)的一致性,導(dǎo)致調(diào)用者無(wú)法解析,所以我們常常會(huì)定義一個(gè)全局的異常攔截器,需要的朋友可以參考下2024-01-01
淺析Java虛擬機(jī)詳解之概述、對(duì)象生存法則
這篇文章主要介紹了Java虛擬機(jī)詳解之概述、對(duì)象生存法則,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04

