一、消息队列的作用
1、异步处理
2、流量削峰
3、应用解耦
4、日志处理
二、此处展示的是异步处理场景
1、构建maven项目,此处不做多余的说明了,导入MQ相关的jar包,注意版本的问题,这里费了好多时间解决冲突
<!-- MQ start-->
//我的spring版本为 4.2.3.RELEASE
// 这里用了mq为 5.11.1的版本,因为5.15以上的版本,
会包含spring的包,导致与spring的包冲突,各种报错,
浪费了好多时间去查找整理
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.11.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.11.1</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>4.6</version>
</dependency>
<!-- MQ end-->
2、写一个处理邮件消息队列的处理类
import javax.jms.Destination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
@Component
public class EmailProcessor {
@Autowired
private JmsTemplate jmsTplate;
public void sendEmailInfo2Queue(Destination destination, String message){
System.out.println("======= 发送邮件的请求消息到消息队列=======");
jmsTplate.convertAndSend(destination, message);
}
}
3、实现消息监听器
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* 实现 消息队列监听器,监听消息队列
* 当监听到队列中有消息时,进行消息消费
* @author Administrator
*
*/
@Component
public class DoSendEmail implements MessageListener{
@Autowired
private EmailSender emailSender;
/**
* 监听的方法实现
*/
public void onMessage(Message message) {
TextMessage textMsg = (TextMessage)message;
try {
JSONObject jsonObject = JSON.parseObject(textMsg.getText());
emailSender.sendEmail(jsonObject.getString("email"),jsonObject.getString("code"),jsonObject.getString("username"));
} catch (JMSException e) {
e.printStackTrace();
}
}
}
4、实现上面使用到的邮件发送类,使用javax.mail类
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.springframework.stereotype.Component;
@Component
public class EmailSender {
// 发送者的邮箱
private static final String FROM_EMAIL_ADDR = "xxx";
// 授权码,即密码
public static final String FROM_MAIL_PWD = "xxx";
public void sendEmail(String to, String code, String username) {
//1、创建一个程序与邮件服务器会话对象 Session
Properties prop = new Properties();
prop.setProperty("mail.transport.protocol", "SMTP");
prop.setProperty("mail.smtp.host","smtp.163.com");
prop.setProperty("mail.smtp.port", "25");
// 指定验证为true
prop.setProperty("mail.smtp.auth", "true");
prop.setProperty("mail.smtp.timeout","1000");
// 验证账号及密码,密码需要是第三方授权码
Authenticator authc = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(FROM_EMAIL_ADDR, FROM_MAIL_PWD);
}
};
Session session = Session.getInstance(prop, authc);
// 2、创建messege
Message msg = new MimeMessage(session);
try {
// 设置发送者邮箱
msg.setFrom(new InternetAddress(FROM_EMAIL_ADDR));
// 设置发送方式与接收者
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
// 设置主题
msg.setSubject("邮件发送测试");
// 设置内容
msg.setContent(code, "text/html;charset=utf-8");
Transport.send(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5、在用户登录验证成功后,加入发送消息队列的代码
// 用户登录后,给用户发送邮件,提示用户登录信息
//此处代码加在验证用户成功,返回页面之前
Destination destination = new ActiveMQQueue("email.queue");
Map<String,String> emailParam = new HashMap<String,String>();
emailParam.put("email","361552730@qq.com");
emailParam.put("code", "ABCDEFG");
emailParam.put("username","FX");
String message = JSON.toJSONString(emailParam);
emailProcessor.sendEmailInfo2Queue(destination,message);
6、配置jms, 本次单独使用一个spring-jms.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress SpringFacetInspection -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd"
>
<!-- 连接MQ -->
<amq:connectionFactory id="amqConnectionFactory" brokerURL="tcp://localhost:61616" userName="admin" password="admin"/>
<!-- 交给spring管理 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="amqConnectionFactory"/>
<property name="sessionCacheSize" value="10"/>
</bean>
<!-- JMS模板 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<!-- 如果为True,则是Topic;如果是false或者默认,则是queue -->
<property name="pubSubDomain" value="false"/>
</bean>
<!-- JMS监听器 -->
<jms:listener-container destination-type="queue" connection-factory="connectionFactory">
<!-- 使用doSendEmail对象 监听 email.queue 的消息队列,当有消息时,进行消费 -->
<jms:listener destination="email.queue" ref="doSendEmail"/>
</jms:listener-container>
</beans>
7、当然要在spring的配置文件中加入
<import resource="spring-jms.xml"/>
8、启动项目,登录,可以发现邮箱中已经收到邮件了。