Spring学习笔记3之消息队列(rabbitmq)发送邮件功能
rabbitmq简介:
mq全称为message queue, 消息队列(mq)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。其中较为成熟的mq产品有ibm websphere mq。
本节的内容是用户注册时,将邮箱地址先存入rabbitmq队列,之后返回给用户注册成功;之后消息队列的接收者从队列中获取消息,发送邮件给用户。
一、rabbitmq介绍
如果之前对rabbitmq不了解,推荐先看一下rabbitmq quick(快速手册)。
1、rabbitmq在mac上的安装。
2、rabbitmq简单介绍。
生产者: 负责发送消息到exchange。
exchange: 按照一定的策略,负责将消息存入到指定的队列。
队列queue: 负责保存消息。
消费者: 负责从队列中提取消息。
binding: 负责exchange和队列的关联映射,exchange和queue是多对多的关系。
二、rabbitmq在spring中的实现
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, 则按默认值localhost:5672, guest/guest--> <!--<connection-factory id="connectionfactory" />--> <connection-factory id="connectionfactory" host="localhost" port="5672" username="everseeker" password="333" /> <!--2、配置队列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> <!--3、配置rabbittemplate发送消息--> <template id="rabbittemplate" connection-factory="connectionfactory" /> <!--4、配置监听器容器和监听器来接收消息--> <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.的错误提示,解决办法是新建一个管理员权限的用户,并允许访问虚拟主机。
步骤如下:
1、打开
2、admin ——> users, 新建用户,administrator权限。
3、virtual hosts,设置新建用户允许访问。
3、生产者发送消息到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); } }
4、配置消费者来接收消息。
public class useralerthandler { public void handleuseralerttoemail(user user) { system.out.println(user); }
三、通过javax.mail来发送邮件
1、引入依赖包。
<dependency> <groupid>javax.mail</groupid> <artifactid>mail</artifactid> <version>1.4.7</version> </dependency>
2、配置邮件服务器信息。
@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; }
3、发送邮件。
@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); } }
4、消费者调用发送邮件方法即可。
1、参考文献:spring实战(第4版)。
2、完整代码在github,地址:。
以上所述是小编给大家介绍的spring学习笔记3之消息队列(rabbitmq)发送邮件功能,希望对大家有所帮助
上一篇: 一道有意思的面试算法题