原来有个教程是关于Javamail的,但是那个是自己写Javamail的发送过程,这次不同的是:使用Spring的Mail功能,使用了消息队列。

先看一下设想的场景

不过本文重点不是消息队列,而是使用spring发送邮件。

首先针对于不会Maven和消息队列的小盆友们

依赖jar包:

spring系列jar包

Javamail

先建立一个封装Mail信息的类:很好理解,里面的成员变量代表(收件人,主题,内容)

package com.mq.entity;

import java.io.Serializable;

public class MailInfo implements Serializable {

    /**
*
*/
private static final long serialVersionUID = -5853264487189248317L;
private String to;
private String subject;
private String content;
public MailInfo() {
}
public MailInfo(String to, String subject, String content) {
this.to = to;
this.subject = subject;
this.content = content;
}
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;
} }

然后呢,在classpath下面整一个属性文件,email.properties

mail.account=用户名
mail.pass=密码
mail.host=smtp.exmail.qq.com
mail.port=465
mail.protocol=smtp mail.debug=true
mail.smtp.auth=true
mail.smtp.ssl.enable=true

注意:企业邮箱不用什么授权码,就是密码

然后classpath下建立spring配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<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:core="http://activemq.apache.org/schema/core" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd">   
<context:component-scan base-package="com.mq.mail"></context:component-scan> <context:property-placeholder location="classpath:email.properties"/> <!-- 使用SSL,企业邮箱必需! -->
<bean id="mailSSLSocketFactory" class="com.sun.mail.util.MailSSLSocketFactory">
<property name="trustAllHosts" value="true"></property>
</bean> <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}"></property>
<property name="port" value="${mail.port}"></property>
<property name="username" value="${mail.account}"></property>
<property name="password" value="${mail.pass}"></property>
<property name="protocol" value="${mail.protocol}"></property>
<property name="defaultEncoding" value="UTF-8"></property>
<!--
-->
<property name="javaMailProperties">
<props>
<!-- 使用SMTP身份验证 -->
<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.account}"></property>
</bean> <bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 线程池维护线程的最少数量 -->
<property name="corePoolSize" value="5" />
<!-- 线程池维护线程的最大数量 -->
<property name="maxPoolSize" value="20" />
<!-- 线程池维护线程所允许的空闲时间 -->
<property name="keepAliveSeconds" value="30000" />
<!-- 线程池所使用的缓冲队列 -->
<property name="queueCapacity" value="1000" />
</bean> </beans>

然后写一个发送邮件类

package com.mq.mail;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component; import com.mq.entity.MailInfo; @Component
public class SendMail { @Autowired
private JavaMailSender javaMailSender;
@Autowired
private SimpleMailMessage simpleMailMessage;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor; public void send(final MailInfo mailInfo){
threadPoolTaskExecutor.execute(new Runnable() { @Override
public void run() {
try {
simpleMailMessage.setTo(mailInfo.getTo());
simpleMailMessage.setSubject(mailInfo.getSubject());
simpleMailMessage.setText(mailInfo.getContent());
javaMailSender.send(simpleMailMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
});
} }

最后写一个测试类:

package com.mq.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mq.entity.MailInfo;
import com.mq.mail.SendMail; public class TestMail { public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:spring-mail.xml");
app.start();
MailInfo mailInfo = new MailInfo("XXX@qq.com", "这是主题", "这是内容");
app.getBean(SendMail.class).send(mailInfo);
app.close();
}
}

结果:

下面是Maven+消息队列的部分

我有两个工程,一个是生产者,一个是消费者。都是Maven的web工程。PS:这两个工程加入了mvc,因为本来想做个好玩的东西的,但是太忙了,先放下了,目前只有利用消息队列发送邮件的部分。这也是为啥依赖这么多的原因。

首先是生产者

Maven依赖:

   <properties>
<spring.version>4.3.9.RELEASE</spring.version>
</properties> <dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</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-all</artifactId>
<version>5.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.0</version>
</dependency> <dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.35</version>
</dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency> <dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency> </dependencies>

建立ActiveMQ的属性文件:activemq.properties

activemq.brokerUrl=tcp://localhost:61616
activemq.userName=admin
activemq.password=admin
activemq.pool.maxConnection=10 activemq.queueName=foodQueue
activemq.topicName=foodTopic

因为是本地测试,我就在windows系统启动了一个ActiveMQ。

下面建立spring-activemq.xml

<?xml version="1.0" encoding="UTF-8"?>
<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:core="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"> <context:component-scan base-package="com.mq.service"></context:component-scan>
<mvc:annotation-driven></mvc:annotation-driven> <context:property-placeholder location="classpath:activemq.properties"/> <!-- Spring提供的ConnectionFactory只是Spring用于管理ConnectionFactory的,
真正产生到JMS服务器链接的ConnectionFactory还得是由JMS服务厂商提供,并且需要把它注入到Spring提供的ConnectionFactory中。 -->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${activemq.brokerUrl}"></property>
<property name="userName" value="${activemq.userName}"></property>
<property name="password" value="${activemq.password}"></property>
</bean> <!-- ActiveMQ为我们提供了一个PooledConnectionFactory,通过往里面注入一个ActiveMQConnectionFactory
可以用来将Connection、Session和MessageProducer池化,这样可以大大的减少我们的资源消耗。 -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory" ref="activeMQConnectionFactory"></property>
<property name="maxConnections" value="${activemq.pool.maxConnection}"></property>
</bean> <!-- ConnectionFactory是用于产生到JMS服务器的链接的,Spring为我们提供了多个ConnectionFactory,有SingleConnectionFactory和CachingConnectionFactory。
SingleConnectionFactory对于建立JMS服务器链接的请求会一直返回同一个链接,并且会忽略Connection的close方法调用。
CachingConnectionFactory继承了SingleConnectionFactory,所以它拥有SingleConnectionFactory的所有功能,同时它还新增了缓存功能,它可以缓存Session、MessageProducer和MessageConsumer。 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="pooledConnectionFactory"></property>
</bean> <!-- 在真正利用JmsTemplate进行消息发送的时候,我们需要知道消息发送的目的地,即destination。
在Jms中有一个用来表示目的地的Destination接口,它里面没有任何方法定义,只是用来做一个标识而已。
当我们在使用JmsTemplate进行消息发送时没有指定destination的时候将使用默认的Destination。
默认Destination可以通过在定义jmsTemplate bean对象时通过属性defaultDestination或defaultDestinationName来进行注入,
defaultDestinationName对应的就是一个普通字符串。在ActiveMQ中实现了两种类型的Destination,
一个是点对点的ActiveMQQueue,另一个就是支持订阅/发布模式的ActiveMQTopic。
在定义这两种类型的Destination时我们都可以通过一个name属性来进行构造 --> <!-- 定义消息队列 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>${activemq.queueName}</value>
</constructor-arg>
</bean> <!-- 定义主题 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg>
<value>${activemq.topicName}</value>
</constructor-arg>
</bean> <!-- 配置JMS模板,Spring提供的JMS工具类,它发送、接收消息。 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
<!--
<property name="defaultDestinationName" value="${activemq.queueName}"></property>
--> <property name="defaultDestination" ref="queueDestination"></property> </bean> </beans>

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:core="http://activemq.apache.org/schema/core"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <import resource="classpath:spring-activemq.xml"/>
</beans>

接下来写代码,目录结构如下:(你不需要考虑controller,以及spring-mvc.xml,以及Food)

建立Mail信息类:

package com.mq.entity;

import java.io.Serializable;

public class MailInfo implements Serializable {

    /**
*
*/
private static final long serialVersionUID = -5853264487189248317L;
private String to;
private String subject;
private String content;
public MailInfo() {
}
public MailInfo(String to, String subject, String content) {
this.to = to;
this.subject = subject;
this.content = content;
}
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;
} }

关于那个Food是我测试着玩的哈哈,满足你的好奇心

package com.mq.entity;

import java.io.Serializable;
import java.util.Date; public class Food implements Serializable { private static final long serialVersionUID = 1L; private String foodName;
private double foodPrice;
private int foodNumber;
private Date orderTime;
public Food() {
}
public Food(String foodName, double foodPrice, int foodNumber, Date orderTime) {
super();
this.foodName = foodName;
this.foodPrice = foodPrice;
this.foodNumber = foodNumber;
this.orderTime = orderTime;
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public double getFoodPrice() {
return foodPrice;
}
public void setFoodPrice(double foodPrice) {
this.foodPrice = foodPrice;
}
public int getFoodNumber() {
return foodNumber;
}
public void setFoodNumber(int foodNumber) {
this.foodNumber = foodNumber;
}
public Date getOrderTime() {
return orderTime;
}
public void setOrderTime(Date orderTime) {
this.orderTime = orderTime;
}
@Override
public String toString() {
return "Food [foodName=" + foodName + ", foodPrice=" + foodPrice + ", foodNumber=" + foodNumber + ", orderTime="
+ orderTime + "]";
} }

消息服务接口

package com.mq.service;

import javax.jms.Destination;

import org.springframework.stereotype.Service;

import com.mq.entity.Food;
import com.mq.entity.MailInfo; @Service
public interface HelloService { void sendMessage(Destination destination, Food food); void sendMail(Destination destination, MailInfo mail);
}

消息服务实现:

package com.mq.service.impl;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSONObject;
import com.mq.entity.Food;
import com.mq.entity.MailInfo;
import com.mq.service.HelloService; @Service
public class HelloServiceImpl implements HelloService { @Autowired
private JmsTemplate jmsTemplate; @Override
public void sendMessage(Destination destination, Food food){
jmsTemplate.send(destination, new MessageCreator() { @Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(JSONObject.toJSONString(food));
// return session.createObjectMessage(new Food("蛋糕", 66.5, 1, new Date()));
}
});
} @Override
public void sendMail(Destination destination, MailInfo mail) {
jmsTemplate.send(destination, new MessageCreator() { @Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(JSONObject.toJSONString(mail));
}
});
} }

最后是测试类,这里使用了springTest。

package com.mq.test;

import javax.jms.Destination;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.mq.entity.MailInfo;
import com.mq.service.HelloService; @ContextConfiguration(locations={"classpath:spring.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest { //@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。 //使用@Autowired的话,想使用名称装配可以结合@Qualifier注解进行使用 //@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定,
//如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 @Autowired
private HelloService helloService; @Autowired
@Qualifier("queueDestination")
private Destination destination; @Test
public void test(){
//helloService.sendMessage(destination, new Food("蛋糕", 66.5, 1, new Date()));
for (int i = 0; i < 1; i++) {
helloService.sendMail(destination, new MailInfo("XXX@qq.com", "Spring java mail"+i, "生产者-消息队列-消费者-spring-mail"));
}
}
}

下面是消费者:

依赖和生产者一样的,这里不重复了。activemq.properties也一样。

邮箱属性文件:

mail.account=用户名
mail.pass=密码
mail.host=smtp.exmail.qq.com
mail.port=465
mail.protocol=smtp mail.debug=true
mail.smtp.auth=true
mail.smtp.ssl.enable=true

spring-activemq.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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:core="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"> <mvc:annotation-driven></mvc:annotation-driven>
<!--
<context:property-placeholder location="classpath:activemq.properties"/>
--> <!-- Spring提供的ConnectionFactory只是Spring用于管理ConnectionFactory的,
真正产生到JMS服务器链接的ConnectionFactory还得是由JMS服务厂商提供,并且需要把它注入到Spring提供的ConnectionFactory中。 -->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${activemq.brokerUrl}"></property>
<property name="userName" value="${activemq.userName}"></property>
<property name="password" value="${activemq.password}"></property>
</bean> <!-- ActiveMQ为我们提供了一个PooledConnectionFactory,通过往里面注入一个ActiveMQConnectionFactory
可以用来将Connection、Session和MessageProducer池化,这样可以大大的减少我们的资源消耗。 -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory" ref="activeMQConnectionFactory"></property>
<property name="maxConnections" value="${activemq.pool.maxConnection}"></property>
</bean> <!-- ConnectionFactory是用于产生到JMS服务器的链接的,Spring为我们提供了多个ConnectionFactory,有SingleConnectionFactory和CachingConnectionFactory。
SingleConnectionFactory对于建立JMS服务器链接的请求会一直返回同一个链接,并且会忽略Connection的close方法调用。
CachingConnectionFactory继承了SingleConnectionFactory,所以它拥有SingleConnectionFactory的所有功能,同时它还新增了缓存功能,它可以缓存Session、MessageProducer和MessageConsumer。 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="pooledConnectionFactory"></property>
</bean> <!-- 在真正利用JmsTemplate进行消息发送的时候,我们需要知道消息发送的目的地,即destination。
在Jms中有一个用来表示目的地的Destination接口,它里面没有任何方法定义,只是用来做一个标识而已。
当我们在使用JmsTemplate进行消息发送时没有指定destination的时候将使用默认的Destination。
默认Destination可以通过在定义jmsTemplate bean对象时通过属性defaultDestination或defaultDestinationName来进行注入,
defaultDestinationName对应的就是一个普通字符串。在ActiveMQ中实现了两种类型的Destination,
一个是点对点的ActiveMQQueue,另一个就是支持订阅/发布模式的ActiveMQTopic。
在定义这两种类型的Destination时我们都可以通过一个name属性来进行构造 --> <!-- 定义消息队列 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>${activemq.queueName}</value>
</constructor-arg>
</bean> <!-- 定义主题 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg>
<value>${activemq.topicName}</value>
</constructor-arg>
</bean> <!-- 装配监听器 -->
<bean id="mqListener" class="com.mq.listener.ActiveMQListener"></bean> <!-- 消费者是如何知道有生产者发送消息到指定目的地Destination了呢?这是通过Spring为我们封装的消息监听容器MessageListenerContainer实现的,它负责接收信息,并把接收到的信息分发给真正的MessageListener进行处理。
我们在配置一个MessageListenerContainer的时候有三个属性必须指定,一个是表示从哪里监听的ConnectionFactory;一个是表示监听什么的Destination;一个是接收到消息以后进行消息处理的MessageListener。
Spring一共为我们提供了两种类型的MessageListenerContainer,SimpleMessageListenerContainer和DefaultMessageListenerContainer。
大多数情况下我们还是使用的DefaultMessageListenerContainer,跟SimpleMessageListenerContainer相比,DefaultMessageListenerContainer会动态的适应运行时需要,并且能够参与外部的事务管理。
-->
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"></property>
<property name="destination" ref="queueDestination"></property>
<property name="messageListener" ref="mqListener"></property>
</bean> </beans>

spring-mail.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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:core="http://activemq.apache.org/schema/core" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd"> <!-- 使用SSL,企业邮箱必需! -->
<bean id="mailSSLSocketFactory" class="com.sun.mail.util.MailSSLSocketFactory">
<property name="trustAllHosts" value="true"></property>
</bean> <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}"></property>
<property name="port" value="${mail.port}"></property>
<property name="username" value="${mail.account}"></property>
<property name="password" value="${mail.pass}"></property>
<property name="protocol" value="${mail.protocol}"></property>
<property name="defaultEncoding" value="UTF-8"></property>
<!--
-->
<property name="javaMailProperties">
<props>
<!-- 使用SMTP身份验证 -->
<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.account}"></property>
</bean> <bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 线程池维护线程的最少数量 -->
<property name="corePoolSize" value="5" />
<!-- 线程池维护线程的最大数量 -->
<property name="maxPoolSize" value="20" />
<!-- 线程池维护线程所允许的空闲时间 -->
<property name="keepAliveSeconds" value="30000" />
<!-- 线程池所使用的缓冲队列 -->
<property name="queueCapacity" value="1000" />
</bean> </beans>

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:core="http://activemq.apache.org/schema/core"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <context:component-scan base-package="com.mq.entity,com.mq.mail"></context:component-scan>
<!-- 不允许有多个属性文件标签,所以只能把项目中的属性文件统一读取 -->
<context:property-placeholder location="classpath:activemq.properties,classpath:email.properties"/>
<import resource="spring-activemq.xml"/>
<import resource="spring-mail.xml"/> </beans>

下面是工程结构:entity不说了,是一样的。

ActiveMQ监听器:

package com.mq.listener;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; import org.springframework.beans.factory.annotation.Autowired; import com.alibaba.fastjson.JSONObject;
import com.mq.entity.MailInfo;
import com.mq.mail.SendMail; public class ActiveMQListener implements MessageListener { @Autowired
private SendMail sendMail; @Override
public void onMessage(Message message) {
TextMessage text = (TextMessage) message; try {
MailInfo mail = JSONObject.parseObject(text.getText(), MailInfo.class);
if(mail != null){
System.out.println(mail.getTo() + "," + mail.getSubject() + "," + mail.getContent());
System.out.println("发送邮件...");
sendMail.send(mail);
}
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // try {
// System.out.println(text.getText());
// Food food = JSONObject.parseObject(text.getText(), Food.class);
// System.out.println("============收到消息===========");
// System.out.println(food);
// } catch (JMSException e) {
// e.printStackTrace();
// } } }

SendMail:

package com.mq.mail;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component; import com.mq.entity.MailInfo; @Component
public class SendMail { @Autowired
private JavaMailSender javaMailSender;
@Autowired
private SimpleMailMessage simpleMailMessage;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor; public void send(final MailInfo mailInfo){
threadPoolTaskExecutor.execute(new Runnable() { @Override
public void run() {
try {
simpleMailMessage.setTo(mailInfo.getTo());
simpleMailMessage.setSubject(mailInfo.getSubject());
simpleMailMessage.setText(mailInfo.getContent());
javaMailSender.send(simpleMailMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
});
} }

最后测试:

package com.mq.test;

import javax.jms.Destination;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @ContextConfiguration(locations={"classpath:spring.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest { //@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。 //使用@Autowired的话,想使用名称装配可以结合@Qualifier注解进行使用 //@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定,
//如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 @Autowired
@Qualifier("queueDestination")
private Destination destination; @Test
public void test(){
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//在单元测试里,如果test方法先于我们要执行的任务结束,会导致任务出错,所以我们这里睡眠了MAX秒,就为了给我们的任务争取时间
}
}

先启动ActiveMQ,然后执行生产者的test方法,

然后执行消费者的test方法。

结果:

你运行的时候记得修改收件人哦,别给我发哦。

QQ企业邮箱+Spring+Javamail+ActiveMQ(发送企业邮件)的更多相关文章

  1. outlook邮箱邮件与企业邮箱同步(outlook本地文件夹邮件,web邮箱里没有)

    用惯了outlook2010, 问题:今天将邮件放到自定义文件夹后,发现在web邮箱中看不到邮件了.不能同步到企业邮箱. 解决忙了一天,才知道是账户类型问题,pop3类型,只下载不上传.所以outlo ...

  2. 【Java Web开发学习】Spring消息-ActiveMQ发送消息

    ActiveMQ发送消息 转载:http://www.cnblogs.com/yangchongxing/p/9042401.html Java消息服务(Java Message Service, J ...

  3. spring整合activemq发送MQ消息[Topic模式]实例

    Topic模式消息发送实例 1.pom引入 <dependency> <groupId>junit</groupId> <artifactId>juni ...

  4. spring整合activemq发送MQ消息[queue模式]实例

    queue类型消息 pom依赖 <dependency> <groupId>junit</groupId> <artifactId>junit</ ...

  5. 腾讯企业邮箱又一次隐藏了qq邮件列表的入口

    今天登陆腾讯企业邮箱,发现腾讯企业邮箱又一次隐藏了qq邮件列表的入口,很不方便操作, 我们切换到工具箱选项,然后随便点击里面的一个工具,比如:企业网盘,然后看浏览器地址栏的地址如下:http://ex ...

  6. spring-boot 速成(10) -【个人邮箱/企业邮箱】发送邮件

    发邮件是一个很常见的功能,代码本身并不复杂,有坑的地方主要在于各家邮件厂家的设置,下面以qq个人邮箱以及腾讯企业邮箱为例,讲解如何用spring-boot发送邮件: 一.添加依赖项 compile ' ...

  7. 解析腾讯企业邮箱到自己域名,设置mail的cname

    之前注册了腾讯企业邮的免费邮箱,后来想把企业邮箱和域名绑定起来,发现了一些问题. 先来看正常的部分,假设你已经注册过了腾讯企业邮箱免费版,并且已经绑定好了域名. 然后在域名提供商那里设置域名解析的MX ...

  8. Apache Commons Email 使用网易企业邮箱发送邮件

    最近使用HtmlEmail 发送邮件,使用网易企业邮箱,发送邮件,死活发不出去!原以为是网易企业邮箱,不支持发送邮箱,后面经过研究发现,是apache htmlEmail 的协议导致,apache E ...

  9. ubuntu 14.04 下evolution邮箱客户端设置(腾讯企业邮箱)

    安装 evolution 有PPA可用,支持 Ubuntu 14.04 及衍生系统.打开终端,输入以下命令: sudo add-apt-repository ppa:fta/gnome3 sudo a ...

随机推荐

  1. poj1426 Find The Multiple(c语言巧解)

    Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36335   Accepted: 151 ...

  2. Java8之集合排序

    1,List<Map<String,Object>>格式 //排序 Comparator<Map<String, Object>> comparator ...

  3. Daily scrum 12.21

    今天ui组反映了一个数据库数据类型的问题,开发人员在完成任务后再去处理. Member Today’s task 林豪森 与学霸其他小组交流,处理整合问题 宋天舒 修复数据库问题 张迎春 修复数据库问 ...

  4. Scrum Meeting NO.8

    Scrum Meeting No.8 1.会议内容 2.任务清单 徐越 序号 近期的任务 进行中 已完成 1 代码重构:前端通讯模块改为HttpClient+Json √ 2 添加对cookies的支 ...

  5. M2 终审

    1.团队成员简介 左边:马腾跃 右边:陈谋 左上:李剑锋  左下:仉伯龙 右:卢惠明 团队成员及博客: 李剑锋:        Blog:      http://www.cnblogs.com/Po ...

  6. 《Linux内核设计与实现》第3章读书整理

    第三章.进程管理 3.1进程 1.进程就是处于执行期的程序,但进程并不仅仅局限于一段可执行程序代码 2.执行线程: 简称线程,是在进程中活动的对象.每个线程都拥有一个独立的程序计数器.进程栈和一组进程 ...

  7. 关于EA和ED的区别

    在申请美国大学本科的过程中,申请的截止时间往往分为两轮:提前申请(Early Decision/Action) 和常规申请 (Regular Decision).提前申请,顾名思义,截止时间会相对早一 ...

  8. [转帖]Nginx 的 TCP 负载均衡介绍

    Nginx 的 TCP 负载均衡介绍 https://www.cnblogs.com/felixzh/ 前几天同事问 nginx的代理 当时以为只有http的 现在看起来还有tcp的可以使用tcp 代 ...

  9. [日常工作]WorkStation 使用端口转发的方式使用宿主机IP地址提供服务

    1. 虚拟机内的地址如果经常变化,或者是想使用宿主机进行网络服务 但是又不想有人能够访问具体的服务器提供机器.. 可以使用宿主机转发虚拟机的端口的方式来进行处理. workstation 比较好实现 ...

  10. Qt_深入了解信号槽(signal&slot)

    转自豆子空间 信号槽机制是Qt编程的基础.通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯.这就将类之间的关系做了最大程度的解耦. 槽函数和普通的C++成员函数没有很大的区别.它们也可以使 ...