先安裝apache-activemq-5.11.1 ,然後啓動activemq.bat
啓動activeMQ的控制檯:http://localhost:8161/admin/,展示圖如下:
解釋:Number Of Pending Messages :等待消費的消息,這個是當前未出隊列的數量;Number Of Consumers :表示消費者數量;Messages Enqueued :進入隊列的消息;( 這個數量只增不減,重啓acmq後會清零);Messages Dequeued :出了隊列的消息 可以理解爲是消費這消費掉的數量 (重啓acmq後會清零)。
二,項目原碼的解析
1.消息消費者:
mail.properties
mail.host=smtp.qq.com mail.port=25 [email protected](消息發送方) mail.password=郵箱的授權碼 mail.debug=true mail.smtp.auth=true mail.smtp.ssl.enable=true [email protected](消息發送方,這個要與上面的要保持一直,不然會出錯)
注:郵箱的授權碼的獲取:郵箱授權碼的獲取方法
spring-mq.xml
<!-- 真正可以產生Connection的ConnectionFactory,由對應的 JMS服務廠商提供 --> <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <!-- ActiveMQ服務地址 --> <property name="brokerURL" value="${mq.brokerURL}" /> <property name="userName" value="${mq.userName}"></property> <property name="password" value="${mq.password}"></property> </bean> <!-- ActiveMQ爲我們提供了一個PooledConnectionFactory,通過往裏面注入一個ActiveMQConnectionFactory 可以用來將Connection、Session和MessageProducer池化,這樣可以大大的減少我們的資源消耗。 要依賴於 activemq-pool包 --> <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"> <property name="connectionFactory" ref="targetConnectionFactory" /> <property name="maxConnections" value="${mq.pool.maxConnections}" /> </bean> <!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory --> <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory --> <property name="targetConnectionFactory" ref="pooledConnectionFactory" /> </bean> <!-- Spring提供的JMS工具類,它可以進行消息發送、接收等 --> <!-- 隊列模板 --> <bean id="activeMqJmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory對象 --> <property name="connectionFactory" ref="connectionFactory"/> <property name="defaultDestinationName" value="${queueName}"></property> </bean> <!--這個是sessionAwareQueue目的地 --> <bean id="sessionAwareQueue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg> <value>${queueName}</value> </constructor-arg> </bean> <!-- 可以獲取session的MessageListener --> <bean id="consumerSessionAwareMessageListener" class="wusc.edu.demo.mqtest.listener.ConsumerSessionAwareMessageListener"></bean> <bean id="sessionAwareListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory" /> <property name="destination" ref="sessionAwareQueue" /> <property name="messageListener" ref="consumerSessionAwareMessageListener" /> </bean>
spring-mail.xml:
<!-- Spring提供的發送電子郵件的高級抽象類 --> <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host" value="${mail.host}" /> <property name="username" value="${mail.username}" /> <property name="password" value="${mail.password}" /> <property name="defaultEncoding" value="UTF-8"></property> <property name="javaMailProperties"> <props> <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.default.from}</value> </property> </bean> <!-- 配置線程池 --> <bean id="threadPool" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 線程池維護線程的最少數量 --> <property name="corePoolSize" value="5" /> <!-- 線程池維護線程所允許的空閒時間 --> <property name="keepAliveSeconds" value="30000" /> <!-- 線程池維護線程的最大數量 --> <property name="maxPoolSize" value="50" /> <!-- 線程池所使用的緩衝隊列 --> <property name="queueCapacity" value="100" /> </bean>
郵件業務處理類
@Component("mailBiz") public class MailBiz { @Autowired private JavaMailSender mailSender;// spring配置中定義 @Autowired private SimpleMailMessage simpleMailMessage;// spring配置中定義 @Autowired private ThreadPoolTaskExecutor threadPool; /** * 發送模板郵件 * * @param mailParamTemp需要設置四個參數 * templateName,toMail,subject,mapModel * @throws Exception * */ public void mailSend(final MailParam mailParam) { threadPool.execute(new Runnable() { public void run() { try { simpleMailMessage.setFrom(simpleMailMessage.getFrom()); // 發送人,從配置文件中取得 simpleMailMessage.setTo(mailParam.getTo()); // 接收人 simpleMailMessage.setSubject(mailParam.getSubject()); simpleMailMessage.setText(mailParam.getContent()); mailSender.send(simpleMailMessage); } catch (MailException e) { throw e; } } }); } }
隊列監聽器 .ConsumerSessionAwareMessageListener
@Component public class ConsumerSessionAwareMessageListener implements SessionAwareMessageListener<Message> { private static final Log log = LogFactory.getLog(ConsumerSessionAwareMessageListener.class); @Autowired private JmsTemplate activeMqJmsTemplate; @Autowired private Destination sessionAwareQueue; @Autowired private MailBiz bailBiz; public synchronized void onMessage(Message message, Session session) { try { ActiveMQTextMessage msg = (ActiveMQTextMessage) message; final String ms = msg.getText(); log.info("==>receive message:" + ms); MailParam mailParam = JSONObject.parseObject(ms, MailParam.class);// 轉換成相應的對象 if (mailParam == null) { return; } try { bailBiz.mailSend(mailParam); } catch (Exception e) { // 發送異常,重新放回隊列 // activeMqJmsTemplate.send(sessionAwareQueue, new MessageCreator() { // public Message createMessage(Session session) throws JMSException { // return session.createTextMessage(ms); // } // }); log.error("==>MailException:", e); } } catch (Exception e) { log.error("==>", e); } } }
異常的處理邏輯現存問題,會出現死循環,所以註釋掉了
郵件參數封裝類 (MailParam)
public class MailParam { /** 發件人 **/ private String from; /** 收件人 **/ private String to; /** 主題 **/ private String subject; /** 郵件內容 **/ private String content; public MailParam() { } public MailParam(String to, String subject, String content) { this.to = to; this.subject = subject; this.content = content; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } 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; } }
ActiveMQ測試啓動類 .
public class MQConsumer { private static final Log log = LogFactory.getLog(MQConsumer.class); public static void main(String[] args) { try { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/spring-context.xml"); context.start(); } catch (Exception e) { log.error("==>MQ context start error:", e); System.exit(0); } } }
項目結構圖如下:
②:消息生產者:
mq.properties
## MQ mq.brokerURL=tcp\://127.0.0.1\:61616 mq.userName=admin mq.password=admin mq.pool.maxConnections=10 #queueName queueName=firstTest
spring-mq.xml:
<!-- 真正可以產生Connection的ConnectionFactory,由對應的 JMS服務廠商提供 --> <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <!-- ActiveMQ服務地址 --> <property name="brokerURL" value="${mq.brokerURL}" /> <property name="userName" value="${mq.userName}"></property> <property name="password" value="${mq.password}"></property> </bean> <!-- ActiveMQ爲我們提供了一個PooledConnectionFactory,通過往裏面注入一個ActiveMQConnectionFactory 可以用來將Connection、Session和MessageProducer池化,這樣可以大大的減少我們的資源消耗。 要依賴於 activemq-pool包 --> <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"> <property name="connectionFactory" ref="targetConnectionFactory" /> <property name="maxConnections" value="${mq.pool.maxConnections}" /> </bean> <!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory --> <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory --> <property name="targetConnectionFactory" ref="pooledConnectionFactory" /> </bean> <!-- Spring提供的JMS工具類,它可以進行消息發送、接收等 --> <!-- 隊列模板 --> <bean id="activeMqJmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory對象 --> <property name="connectionFactory" ref="connectionFactory"/> <property name="defaultDestinationName" value="${queueName}"></property> </bean>
ActiveMQ測試啓動類
public class MQProducerTest { private static final Log log = LogFactory.getLog(MQProducerTest.class); public static void main(String[] args) { try { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/spring-context.xml"); context.start(); MQProducer mqProducer = (MQProducer) context.getBean("mqProducer"); // 郵件發送 MailParam mail = new MailParam(); mail.setTo("你要接收的郵箱"); mail.setSubject("ActiveMQ測試"); mail.setContent("通過ActiveMQ異步發送郵件!"); mqProducer.sendMessage(mail); context.stop(); } catch (Exception e) { log.error("==>MQ context start error:", e); System.exit(0); } finally { log.info("===>System.exit"); System.exit(0); } } }
項目結構圖:
這樣就可以了。