Spring學習筆記3——消息隊列(rabbitmq), 發送郵件

    本節的內容是用戶註冊時,將郵箱地址先存入rabbitmq隊列,以後返回給用戶註冊成功;以後消息隊列的接收者從隊列中獲取消息,發送郵件給用戶。html

 

1、RabbitMQ介紹java

    若是以前對rabbitmq不瞭解,推薦先看一下RabbitMQ Quick(快速手冊)git

一、rabbitmq在mac上的安裝github

二、rabbitmq簡單介紹。spring

生產者: 負責發送消息到Exchange。服務器

Exchange: 按照必定的策略,負責將消息存入到指定的隊列。socket

隊列queue:  負責保存消息。ui

消費者: 負責從隊列中提取消息。this

binding: 負責Exchange和隊列的關聯映射,Exchange和queue是多對多的關係。spa

 

2、RabbitMQ在Spring中的實現

一、引入依賴包。

<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>

二、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">

    <!--一、配置鏈接工廠, 若是不配置host, port, username, passowrd, 則按默認值localhost:5672, guest/guest-->
    <!--<connection-factory id="connectionFactory" />-->
    <connection-factory id="connectionFactory"
                        host="localhost"
                        port="5672"
                        username="everSeeker"
                        password="333" />

    <!--二、配置隊列queue, Exchange, 以及將他們結合在一塊兒的binding-->
    <!--在queue以及exchange中, 有一個重要的屬性durable, 默認爲true, 能夠防止宕機後數據丟失。-->
    <!--在listener-container中, 有acknowledge屬性, 默認爲auto, 即消費者成功處理消息後必須有個應答, 若是消費者程序發生異常或者宕機, 消息會被從新放回隊列-->
    <admin connection-factory="connectionFactory" />
    <queue id="userAlertEmailQueue" name="user.alerts.email" durable="true" />
    <queue id="userAlertCellphoneQueue" name="user.alerts.cellphone" />     <!--durable默認爲true-->

    <!--標準的AMQP Exchange有4種: Direct, Topic, Headers, Fanout, 根據實際須要選擇。-->
    <!--Direct: 若是消息的routing key與bingding的routing key直接匹配的話, 消息將會路由到該隊列上。-->
    <!--Topic: 若是消息的routing key與bingding的routing key符合通配符匹配的話, 消息將會路由到該隊列上。-->
    <!--Headers: 若是消息參數表中的頭信息和值都與binding參數表中相匹配, 消息將會路由到該隊列上。-->
    <!--Fanout: 無論消息的routing key和參數表的頭信息/值是什麼, 消息將會路由到該隊列上。-->
    <direct-exchange name="user.alert.email.exchange" durable="true">
        <bindings>
            <binding queue="user.alerts.email" />     <!--默認的routing key與隊列的名稱相同-->
        </bindings>
    </direct-exchange>
    <direct-exchange name="user.alert.cellphone.exchange">
        <bindings>
            <binding queue="user.alerts.cellphone" />
        </bindings>
    </direct-exchange>

    <!--三、配置RabbitTemplate發送消息-->
    <template id="rabbitTemplate"
              connection-factory="connectionFactory" />

    <!--四、配置監聽器容器和監聽器來接收消息-->
    <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時,採用默認的guest/guest帳號密碼時,有可能會出現org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.的錯誤提示,解決辦法是新建一個管理員權限的用戶,並容許訪問虛擬主機。步驟以下:

一、打開http://localhost:15672/
二、Admin ——> Users, 新建用戶,administrator權限。
三、Virtual Hosts,設置新建用戶容許訪問。

三、生產者發送消息到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), 將對象object封裝成Message對象後, 發送給exchange
        rabbit.convertAndSend("user.alert.email.exchange", "user.alerts.email", user);
    }
}

四、配置消費者來接收消息。

public class UserAlertHandler {
    
    public void handleUserAlertToEmail(User user) {
        System.out.println(user);
}

 

3、經過javax.mail來發送郵件

一、引入依賴包。

<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4.7</version>
</dependency>

二、配置郵件服務器信息。

@Bean
public MailSender mailSender(Environment env) {
    JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
    //若是爲普通郵箱, 非ssl認證等, 好比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"); //若是郵件服務器採用了ssl認證, 增長如下配置, 好比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;
}

三、發送郵件。

@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() + "信息確認"); message.setText(user.toString()); mailSender.send(message);
    }
}

四、消費者調用發送郵件方法便可。

 

一、參考文獻:Spring實戰(第4版)。

二、完整代碼在github,地址:https://github.com/everseeker0307/spring-demo

相關文章
相關標籤/搜索