摘要:本文以一個非常簡單的業(yè)務(wù)場景為例,即系統(tǒng)給用戶發(fā)送通知郵件,來講一講如何構(gòu)建簡單的消息通信。實現(xiàn)生產(chǎn)者和消費者在這里生產(chǎn)者負(fù)責(zé)生成包含郵件收件人和內(nèi)容等信息的消息并存入隊列,而消費者則負(fù)責(zé)從這些信息中國生成郵件并發(fā)送出去。
前言
對于WEB系統(tǒng),向用戶發(fā)送郵件、短信、站內(nèi)信等幾乎是必備的基礎(chǔ)功能,但這些任務(wù)相對于所見即所得的立即響應(yīng)式的請求對實時性的要求并不高,同時任務(wù)處理的量還很大。在復(fù)雜多系統(tǒng)的情形下,還要考慮多個子系統(tǒng)的通信問題。無論是從實際業(yè)務(wù)需求還是從軟件工程的設(shè)計角度出發(fā),消息通信都有必要成為一個獨立的模塊。本文以一個非常簡單的業(yè)務(wù)場景為例,即系統(tǒng)給用戶發(fā)送通知郵件,來講一講如何構(gòu)建簡單的消息通信。
引入JMS在上一次的博客中我們講述了消息隊列,消息隊列是消息通信系統(tǒng)的重要組成部分。J2EE為運行在jvm虛擬機上的程序間的通信早就制定了一套標(biāo)準(zhǔn),也就是我們提到的JMS標(biāo)準(zhǔn)。但JMS并不涉及到具體實現(xiàn),我們在本文中采用應(yīng)用最為廣泛的ActiveMQ為例。
首先我們需要在pom.xml中引入相關(guān)依賴。
配置JMS和ActiveMQorg.springframework spring-jms ${spring.version} org.apache.activemq activemq-core 5.7.0
然后我們要在ApplicationContext.xml文件中作出相關(guān)配置。
JMS簡單應(yīng)用配置
對于上文我們將一一解釋:
ConnectionFactory:用于產(chǎn)生到JMS服務(wù)器的鏈接
targetConnectionFactory:真正可以產(chǎn)生Connection的ConnectionFactory,由對應(yīng)的 JMS服務(wù)廠商提供,在這里是ActiveMQ
JmsTemplate:實現(xiàn)消息發(fā)送的工具,由Spring提供
Destination:用來表示目的地的接口在ActiveMQ中實現(xiàn)了兩種類型的Destination,一個是點對點的ActiveMQQueue,另一個就是支持訂閱/發(fā)布模式的ActiveMQTopic。,沒有任何方法定義,只是用來做一個標(biāo)識而已。
實現(xiàn)生產(chǎn)者和消費者在這里生產(chǎn)者負(fù)責(zé)生成包含郵件收件人和內(nèi)容等信息的消息并存入隊列,而消費者則負(fù)責(zé)從這些信息中國生成郵件并發(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回調(diào)函數(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; /**郵件內(nèi)容**/ 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("[email protected]"); msg.setTo("[email protected]"); msg.setSubject("用戶修改通知"); // 將用戶名與當(dāng)期日期格式化到郵件內(nèi)容的字符串模板 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("[email protected]");//發(fā)件人 helper.setTo(InternetAddress.parse(email.getAddress()));//收件人 helper.setReplyTo("[email protected]");//回復(fù)到 helper.setSubject(email.getSubject());//郵件主題 helper.setText(email.getContent(), true);//true表示設(shè)定html格式 mailSender.send(mime); } /** * Spring的MailSender. */ public void setMailSender(JavaMailSender mailSender) { this.mailSender = mailSender; } /** * 郵件內(nèi)容的字符串模板. */ public void setTextTemplate(String textTemplate) { this.textTemplate = textTemplate; } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/64640.html
摘要:對于與而言,則可以看做是消息傳遞技術(shù)的一種衍生或封裝。在生產(chǎn)者通知消費者時,傳遞的往往是消息或事件,而非生產(chǎn)者自身。通過消息路由,我們可以配置路由規(guī)則指定消息傳遞的路徑,以及指定具體的消費者消費對應(yīng)的生產(chǎn)者。采用和來進行遠程對象的通訊。 消息模式 歸根結(jié)底,企業(yè)應(yīng)用系統(tǒng)就是對數(shù)據(jù)的處理,而對于一個擁有多個子系統(tǒng)的企業(yè)應(yīng)用系統(tǒng)而言,它的基礎(chǔ)支撐無疑就是對消息的處理。與對象不同,消息本質(zhì)上...
摘要:微軟的雖然引入了事件機制,可以在隊列收到消息時觸發(fā)事件,通知訂閱者。由微軟作為主要貢獻者的,則對以及做了進一層包裝,并能夠很好地實現(xiàn)這一模式。 在分布式服務(wù)框架中,一個最基礎(chǔ)的問題就是遠程服務(wù)是怎么通訊的,在Java領(lǐng)域中有很多可實現(xiàn)遠程通訊的技術(shù),例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,這些名詞之間到底是些什么關(guān)系呢,它們背后到底是基...
摘要:微軟的雖然引入了事件機制,可以在隊列收到消息時觸發(fā)事件,通知訂閱者。由微軟作為主要貢獻者的,則對以及做了進一層包裝,并能夠很好地實現(xiàn)這一模式。 在分布式服務(wù)框架中,一個最基礎(chǔ)的問題就是遠程服務(wù)是怎么通訊的,在Java領(lǐng)域中有很多可實現(xiàn)遠程通訊的技術(shù),例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,這些名詞之間到底是些什么關(guān)系呢,它們背后到底是基...
摘要:而中的消息中間件則是在常見的消息中間件類型無疑是不錯的選擇。是在之間傳遞的消息的對象?;竟δ苁怯糜诤兔嫦蛳⒌闹虚g件相互通信的應(yīng)用程序接口。支持兩種消息發(fā)送和接收模型。一種稱為模型,即采用點對點的方式發(fā)送消息。 消息中間件利用高效可靠的消息傳遞機制進行平臺無關(guān)的數(shù)據(jù)交流,并基于數(shù)據(jù)通信來進行分布式系統(tǒng)的集成。通過提供消息傳遞和消息排隊模型,它可以在分布式環(huán)境下擴展進程間的通信。而Ja...
閱讀 1554·2023-04-25 18:56
閱讀 1499·2021-09-29 09:34
閱讀 1717·2021-09-22 15:51
閱讀 3520·2021-09-14 18:03
閱讀 1173·2021-07-23 17:54
閱讀 2031·2019-08-29 18:38
閱讀 2911·2019-08-29 12:38
閱讀 619·2019-08-26 13:41