QQ企业邮箱+Spring+Javamail+ActiveMQ(发送企业邮件)
原来有个教程是关于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(发送企业邮件)的更多相关文章
- outlook邮箱邮件与企业邮箱同步(outlook本地文件夹邮件,web邮箱里没有)
用惯了outlook2010, 问题:今天将邮件放到自定义文件夹后,发现在web邮箱中看不到邮件了.不能同步到企业邮箱. 解决忙了一天,才知道是账户类型问题,pop3类型,只下载不上传.所以outlo ...
- 【Java Web开发学习】Spring消息-ActiveMQ发送消息
ActiveMQ发送消息 转载:http://www.cnblogs.com/yangchongxing/p/9042401.html Java消息服务(Java Message Service, J ...
- spring整合activemq发送MQ消息[Topic模式]实例
Topic模式消息发送实例 1.pom引入 <dependency> <groupId>junit</groupId> <artifactId>juni ...
- spring整合activemq发送MQ消息[queue模式]实例
queue类型消息 pom依赖 <dependency> <groupId>junit</groupId> <artifactId>junit</ ...
- 腾讯企业邮箱又一次隐藏了qq邮件列表的入口
今天登陆腾讯企业邮箱,发现腾讯企业邮箱又一次隐藏了qq邮件列表的入口,很不方便操作, 我们切换到工具箱选项,然后随便点击里面的一个工具,比如:企业网盘,然后看浏览器地址栏的地址如下:http://ex ...
- spring-boot 速成(10) -【个人邮箱/企业邮箱】发送邮件
发邮件是一个很常见的功能,代码本身并不复杂,有坑的地方主要在于各家邮件厂家的设置,下面以qq个人邮箱以及腾讯企业邮箱为例,讲解如何用spring-boot发送邮件: 一.添加依赖项 compile ' ...
- 解析腾讯企业邮箱到自己域名,设置mail的cname
之前注册了腾讯企业邮的免费邮箱,后来想把企业邮箱和域名绑定起来,发现了一些问题. 先来看正常的部分,假设你已经注册过了腾讯企业邮箱免费版,并且已经绑定好了域名. 然后在域名提供商那里设置域名解析的MX ...
- Apache Commons Email 使用网易企业邮箱发送邮件
最近使用HtmlEmail 发送邮件,使用网易企业邮箱,发送邮件,死活发不出去!原以为是网易企业邮箱,不支持发送邮箱,后面经过研究发现,是apache htmlEmail 的协议导致,apache E ...
- ubuntu 14.04 下evolution邮箱客户端设置(腾讯企业邮箱)
安装 evolution 有PPA可用,支持 Ubuntu 14.04 及衍生系统.打开终端,输入以下命令: sudo add-apt-repository ppa:fta/gnome3 sudo a ...
随机推荐
- poj1426 Find The Multiple(c语言巧解)
Find The Multiple Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 36335 Accepted: 151 ...
- Java8之集合排序
1,List<Map<String,Object>>格式 //排序 Comparator<Map<String, Object>> comparator ...
- Daily scrum 12.21
今天ui组反映了一个数据库数据类型的问题,开发人员在完成任务后再去处理. Member Today’s task 林豪森 与学霸其他小组交流,处理整合问题 宋天舒 修复数据库问题 张迎春 修复数据库问 ...
- Scrum Meeting NO.8
Scrum Meeting No.8 1.会议内容 2.任务清单 徐越 序号 近期的任务 进行中 已完成 1 代码重构:前端通讯模块改为HttpClient+Json √ 2 添加对cookies的支 ...
- M2 终审
1.团队成员简介 左边:马腾跃 右边:陈谋 左上:李剑锋 左下:仉伯龙 右:卢惠明 团队成员及博客: 李剑锋: Blog: http://www.cnblogs.com/Po ...
- 《Linux内核设计与实现》第3章读书整理
第三章.进程管理 3.1进程 1.进程就是处于执行期的程序,但进程并不仅仅局限于一段可执行程序代码 2.执行线程: 简称线程,是在进程中活动的对象.每个线程都拥有一个独立的程序计数器.进程栈和一组进程 ...
- 关于EA和ED的区别
在申请美国大学本科的过程中,申请的截止时间往往分为两轮:提前申请(Early Decision/Action) 和常规申请 (Regular Decision).提前申请,顾名思义,截止时间会相对早一 ...
- [转帖]Nginx 的 TCP 负载均衡介绍
Nginx 的 TCP 负载均衡介绍 https://www.cnblogs.com/felixzh/ 前几天同事问 nginx的代理 当时以为只有http的 现在看起来还有tcp的可以使用tcp 代 ...
- [日常工作]WorkStation 使用端口转发的方式使用宿主机IP地址提供服务
1. 虚拟机内的地址如果经常变化,或者是想使用宿主机进行网络服务 但是又不想有人能够访问具体的服务器提供机器.. 可以使用宿主机转发虚拟机的端口的方式来进行处理. workstation 比较好实现 ...
- Qt_深入了解信号槽(signal&slot)
转自豆子空间 信号槽机制是Qt编程的基础.通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯.这就将类之间的关系做了最大程度的解耦. 槽函数和普通的C++成员函数没有很大的区别.它们也可以使 ...