摘要:本文以一個非常簡單的業(yè)務場景為例,即系統(tǒng)給用戶發(fā)送通知郵件,來講一講如何構建簡單的消息通信。實現(xiàn)生產(chǎn)者和消費者在這里生產(chǎn)者負責生成包含郵件收件人和內容等信息的消息并存入隊列,而消費者則負責從這些信息中國生成郵件并發(fā)送出去。
前言
對于WEB系統(tǒng),向用戶發(fā)送郵件、短信、站內信等幾乎是必備的基礎功能,但這些任務相對于所見即所得的立即響應式的請求對實時性的要求并不高,同時任務處理的量還很大。在復雜多系統(tǒng)的情形下,還要考慮多個子系統(tǒng)的通信問題。無論是從實際業(yè)務需求還是從軟件工程的設計角度出發(fā),消息通信都有必要成為一個獨立的模塊。本文以一個非常簡單的業(yè)務場景為例,即系統(tǒng)給用戶發(fā)送通知郵件,來講一講如何構建簡單的消息通信。
引入JMS在上一次的博客中我們講述了消息隊列,消息隊列是消息通信系統(tǒng)的重要組成部分。J2EE為運行在jvm虛擬機上的程序間的通信早就制定了一套標準,也就是我們提到的JMS標準。但JMS并不涉及到具體實現(xiàn),我們在本文中采用應用最為廣泛的ActiveMQ為例。
首先我們需要在pom.xml中引入相關依賴。
配置JMS和ActiveMQorg.springframework spring-jms ${spring.version} org.apache.activemq activemq-core 5.7.0
然后我們要在ApplicationContext.xml文件中作出相關配置。
JMS簡單應用配置
對于上文我們將一一解釋:
ConnectionFactory:用于產(chǎn)生到JMS服務器的鏈接
targetConnectionFactory:真正可以產(chǎn)生Connection的ConnectionFactory,由對應的 JMS服務廠商提供,在這里是ActiveMQ
JmsTemplate:實現(xiàn)消息發(fā)送的工具,由Spring提供
Destination:用來表示目的地的接口在ActiveMQ中實現(xiàn)了兩種類型的Destination,一個是點對點的ActiveMQQueue,另一個就是支持訂閱/發(fā)布模式的ActiveMQTopic。,沒有任何方法定義,只是用來做一個標識而已。
實現(xiàn)生產(chǎn)者和消費者在這里生產(chǎn)者負責生成包含郵件收件人和內容等信息的消息并存入隊列,而消費者則負責從這些信息中國生成郵件并發(fā)送出去。
生產(chǎn)者代碼
public class NotifyMessageProducer { private JmsTemplate jmsTemplate; private Destination notifyQueue; private Destination notifyTopic; public void sendQueue(final User user) { sendMessage(user, notifyQueue); } public void sendTopic(final User user) { sendMessage(user, notifyTopic); } /** * 使用jmsTemplate最簡便的封裝convertAndSend()發(fā)送Map類型的消息. */ private void sendMessage(User user, Destination destination) { Map map = new HashMap(); map.put("userName", user.getName()); map.put("email", user.getEmail()); jmsTemplate.convertAndSend(destination, map); } public void setJmsTemplate(JmsTemplate jmsTemplate) { this.jmsTemplate = jmsTemplate; } public void setNotifyQueue(Destination notifyQueue) { this.notifyQueue = notifyQueue; } public void setNotifyTopic(Destination nodifyTopic) { this.notifyTopic = nodifyTopic; } }
消費者代碼
public class NotifyMessageListener implements MessageListener { private static Logger logger = LoggerFactory.getLogger(NotifyMessageListener.class); @Autowired(required = false) private MailService simpleMailService; /** * MessageListener回調函數(shù). */ @Override public void onMessage(Message message) { try { MapMessage mapMessage = (MapMessage) message; // 打印消息詳情 logger.info("UserName:{}, Email:{}", mapMessage.getString("userName"), mapMessage.getString("email")); // 發(fā)送郵件 if (simpleMailService != null) { simpleMailService.sendNotificationMail(mapMessage.getString("userName")); } } catch (Exception e) { logger.error("處理消息時發(fā)生異常.", e); } } }
郵件模型
public class ApplicationEmail implements Serializable { public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getCc() { return cc; } public void setCc(String cc) { this.cc = cc; } 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; } /**收件人**/ private String address; /**抄送給**/ private String cc; /**郵件主題**/ private String subject; /**郵件內容**/ private String content; /**附件**/ //private MultipartFile[] attachment = new MultipartFile[0]; }
郵件幫助類(此處采用了java mail依賴包)
public class MailService { private static Logger logger = LoggerFactory.getLogger(MailService.class); private JavaMailSender mailSender; private String textTemplate; /** * 發(fā)送純文本的用戶修改通知郵件. */ public void sendNotificationMail(String userName) { SimpleMailMessage msg = new SimpleMailMessage(); msg.setFrom("suemi94@qq.com"); msg.setTo("suemi994@gmail.com"); msg.setSubject("用戶修改通知"); // 將用戶名與當期日期格式化到郵件內容的字符串模板 String content = String.format(textTemplate, userName, new Date()); msg.setText(content); try { mailSender.send(msg); if (logger.isInfoEnabled()) { logger.info("純文本郵件已發(fā)送至{}", StringUtils.join(msg.getTo(), ",")); } } catch (Exception e) { logger.error("發(fā)送郵件失敗", e); } } /** * 同步發(fā)送郵件 * * @param email * @throws MessagingException * @throws IOException */ public void sendMailBySynchronizationMode(ApplicationEmail email) throws MessagingException, IOException { Session session=Session.getDefaultInstance(new Properties()); MimeMessage mime= new MimeMessage(session); MimeMessageHelper helper = new MimeMessageHelper(mime, true, "utf-8"); helper.setFrom("suemi94@qq.com");//發(fā)件人 helper.setTo(InternetAddress.parse(email.getAddress()));//收件人 helper.setReplyTo("suemi94@qq.com");//回復到 helper.setSubject(email.getSubject());//郵件主題 helper.setText(email.getContent(), true);//true表示設定html格式 mailSender.send(mime); } /** * Spring的MailSender. */ public void setMailSender(JavaMailSender mailSender) { this.mailSender = mailSender; } /** * 郵件內容的字符串模板. */ public void setTextTemplate(String textTemplate) { this.textTemplate = textTemplate; } }
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/64640.html
摘要:對于與而言,則可以看做是消息傳遞技術的一種衍生或封裝。在生產(chǎn)者通知消費者時,傳遞的往往是消息或事件,而非生產(chǎn)者自身。通過消息路由,我們可以配置路由規(guī)則指定消息傳遞的路徑,以及指定具體的消費者消費對應的生產(chǎn)者。采用和來進行遠程對象的通訊。 消息模式 歸根結底,企業(yè)應用系統(tǒng)就是對數(shù)據(jù)的處理,而對于一個擁有多個子系統(tǒng)的企業(yè)應用系統(tǒng)而言,它的基礎支撐無疑就是對消息的處理。與對象不同,消息本質上...
摘要:微軟的雖然引入了事件機制,可以在隊列收到消息時觸發(fā)事件,通知訂閱者。由微軟作為主要貢獻者的,則對以及做了進一層包裝,并能夠很好地實現(xiàn)這一模式。 在分布式服務框架中,一個最基礎的問題就是遠程服務是怎么通訊的,在Java領域中有很多可實現(xiàn)遠程通訊的技術,例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,這些名詞之間到底是些什么關系呢,它們背后到底是基...
摘要:微軟的雖然引入了事件機制,可以在隊列收到消息時觸發(fā)事件,通知訂閱者。由微軟作為主要貢獻者的,則對以及做了進一層包裝,并能夠很好地實現(xiàn)這一模式。 在分布式服務框架中,一個最基礎的問題就是遠程服務是怎么通訊的,在Java領域中有很多可實現(xiàn)遠程通訊的技術,例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,這些名詞之間到底是些什么關系呢,它們背后到底是基...
摘要:而中的消息中間件則是在常見的消息中間件類型無疑是不錯的選擇。是在之間傳遞的消息的對象。基本功能是用于和面向消息的中間件相互通信的應用程序接口。支持兩種消息發(fā)送和接收模型。一種稱為模型,即采用點對點的方式發(fā)送消息。 消息中間件利用高效可靠的消息傳遞機制進行平臺無關的數(shù)據(jù)交流,并基于數(shù)據(jù)通信來進行分布式系統(tǒng)的集成。通過提供消息傳遞和消息排隊模型,它可以在分布式環(huán)境下擴展進程間的通信。而Ja...
閱讀 1543·2023-04-25 18:56
閱讀 1496·2021-09-29 09:34
閱讀 1716·2021-09-22 15:51
閱讀 3506·2021-09-14 18:03
閱讀 1168·2021-07-23 17:54
閱讀 2027·2019-08-29 18:38
閱讀 2908·2019-08-29 12:38
閱讀 618·2019-08-26 13:41