文档章节

使用JMS完成消息通信

suemi94
 suemi94
发布于 2016/06/20 13:59
字数 1260
阅读 17
收藏 0

引入JMS

在上一次的博客中我们讲述了消息队列,消息队列是消息通信系统的重要组成部分。J2EE为运行在jvm虚拟机上的程序间的通信早就制定了一套标准,也就是我们提到的JMS标准。但JMS并不涉及到具体实现,我们在本文中采用应用最为广泛的ActiveMQ为例。

首先我们需要在pom.xml中引入相关依赖。

<!-- JMS -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-core</artifactId>
			<version>5.7.0</version>
		</dependency>

配置JMS和ActiveMQ

然后我们要在ApplicationContext.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
	<description>JMS简单应用配置</description>
	<!-- ActiveMQ 连接工厂 -->
	<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="${jms.broker_url}" />
	</bean>
	<!-- Spring Caching 连接工厂 -->
	<bean id="cachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
		<property name="targetConnectionFactory" ref="connectionFactory" />
		<property name="sessionCacheSize" value="10" />
	</bean>
	<!-- Queue定义 -->
	<bean id="notifyQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="q.notify" />
	</bean>
	<!-- Topic定义 -->
	<bean id="notifyTopic" class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg value="t.notify" />
	</bean>
	<!-- Spring JMS Template -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="cachingConnectionFactory" />
	</bean>
	<!-- 使用Spring JmsTemplate的消息生产者 -->
	<bean id="notifyMessageProducer" class="jseed.util.modules.jms.NotifyMessageProducer">
		<property name="jmsTemplate" ref="jmsTemplate" />
		<property name="notifyQueue" ref="notifyQueue" />
		<property name="notifyTopic" ref="notifyTopic" />
	</bean>
	<!-- 异步接收Queue消息Container -->
	<bean id="queueContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="notifyQueue" />
		<property name="messageListener" ref="notifyMessageListener" />
		<property name="concurrentConsumers" value="10" />
	</bean>
	<!-- 异步接收Topic消息Container -->
	<bean id="topicContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="notifyTopic" />
		<property name="messageListener" ref="notifyMessageListener" />
	</bean>
	<!-- 异步接收消息处理类 -->
	<bean id="notifyMessageListener" class="jseed.util.modules.jms.NotifyMessageListener" />
</beans>

对于上文我们将一一解释:

  • ConnectionFactory:用于产生到JMS服务器的链接
  • targetConnectionFactory:真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供,在这里是ActiveMQ
  • JmsTemplate:实现消息发送的工具,由Spring提供
  • Destination:用来表示目的地的接口在ActiveMQ中实现了两种类型的Destination,一个是点对点的ActiveMQQueue,另一个就是支持订阅/发布模式的ActiveMQTopic。,没有任何方法定义,只是用来做一个标识而已。

实现生产者和消费者

在这里生产者负责生成包含邮件收件人和内容等信息的消息并存入队列,而消费者则负责从这些信息中国生成邮件并发送出去。

  • 生产者代码
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()发送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回调函数.
	 */
	@Override
	public void onMessage(Message message) {
		try {
			MapMessage mapMessage = (MapMessage) message;
			// 打印消息详情
			logger.info("UserName:{}, Email:{}", mapMessage.getString("userName"), mapMessage.getString("email"));

			// 发送邮件
			if (simpleMailService != null) {
				simpleMailService.sendNotificationMail(mapMessage.getString("userName"));
			}
		} catch (Exception e) {
			logger.error("处理消息时发生异常.", 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;

    /**
     * 发送纯文本的用户修改通知邮件.
     */
    public void sendNotificationMail(String userName) {
        SimpleMailMessage msg = new SimpleMailMessage();
        msg.setFrom("suemi94@163.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("纯文本邮件已发送至{}", StringUtils.join(msg.getTo(), ","));
            }
        } catch (Exception e) {
            logger.error("发送邮件失败", e);
        }
    }
    
    /**
     * 同步发送邮件
     * 
     * @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@163.com");//发件人    
         helper.setTo(InternetAddress.parse(email.getAddress()));//收件人    
         helper.setReplyTo("suemi94@163.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;
    }
}

© 著作权归作者所有

上一篇: 也来谈谈RPC
下一篇: Hibernate映射关系
suemi94
粉丝 17
博文 21
码字总数 57847
作品 0
海淀
程序员
私信 提问
搭建JEESZ分布式架构--消息中间件简介

消息中间件在JEESZ分布式架构中的作用 1) 消息中间件在分布式系统中完成消息的发送和接收。 2) 消息中间件可利用高效可靠的消息传递机制进行平台无关的数据交流, 并基于数据通信来进行分布式...

明理萝
2018/08/14
10
1
跟我学习dubbo-消息中间件在分布式系统中的作用介绍(8)

消息中间件在分布式系统中的作用介绍 消息中间件的定义 Message-oriented middleware (MOM) is software infrastructure focused on sending and receiving messages between distributed s......

HI曲奇饼干
2016/01/18
287
4
J2EE平台简介 

1.1.1 J2EE规范 J2EE(Java 2 Platform,Enterprise Edition)是SUN公司定义的一个开发分布式企业级应用的规范。它提供了一个多层次的分布式应用模型和一系列开发技术规范。多层次分布式应用模...

曾赛
2009/09/06
392
0
消息中间件系列三、JMS和activeMQ的简单使用

一、JMS 1、什么是JMS   JMS(JAVA Message Service,java消息服务)本质是API,Java平台消息中间件的规范,java应用程序之间进行消息交换。并且通过提供标准的产生、发送、接收消息的接口简...

我巴巴
2018/10/06
0
0
一步一步Spring整合JMS

1.1 JMS简介 JMS的全称是Java Message Service,即Java消息服务。它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息。把它应用到实际的业务需求中的话...

摆渡者
2015/08/31
425
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 如果是个帅小伙你愿意和他出去吗

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐:《Ghost 》游戏《死亡搁浅》原声 《Ghost 》游戏(《死亡搁浅》原声) - Au/Ra / Alan Walker 手机党少年们想听歌,请使劲儿戳...

小小编辑
56分钟前
98
5
java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
16
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部