一、什么是JMS

  JMS是java message service的缩写即java消息服务,是java定义的消息中间件(MOM)的技术规范(类似玉JDBC)。用于程序之间的异步通信,如果两个应用程序需要通信,则可以通过JMS来进行转发,达到解耦的目的。

二、JMS的消息模型

  JMS有两种消息模型:

    1、点对点或队列模型(Point-to-Point Messaging Domain):消息的生产者将生产出的消息加入到一个队列中,消息的接受者从队列中获取消息。队列保留着消息,直到他们被消费或者超时。

      特点:①每个消息都只有一个消费者,如果队列中的消息被某个消费者消费,该消息会移出队列。

         ②消息的生产者和消费者之间没有时间的约束,生产者可以生产消息,无论消费者是否在运行。同样只要消息队列中有消息,消费者就可以消费和生产者的状态无关。

         ③消费者接受完消息之后要向队列反馈成功的信息。

    2、发布订阅模型(Publish/Subscribe Messaging Domain ):发布者发布消息,所有的订阅者都会接受到消息。

      特点:①发布一个消息会有多个订阅者接受到消息

         ②消息发布者和订阅者之间有时间上的相关性。订阅一个主题的订阅者只能接收到自它订阅之后发布的消息。JMS规范允许客户创建持久订阅,这在一定程度上放松了时间上的相关性要求。持久订阅允许订阅者接受它在未处于激活状态时发送的消息。

三、JMS的对象模型

  1、连接工厂(ConnectionFactory):用于创建JMS连接

  2、JMS连接(Connection):表示JMS客户端和服务器端之间的一个活动的连接,是由客户端通过调用连接工厂的方法建立的。

  3、JMS会话(Session):表示JMS客户与JMS服务器之间的会话状态。JMS会话建立在JMS连接上,表示客户与服务器之间的一个会话线程。

  4、JMS目的地(Destination):生产者发送消息的地方。点对点模式中的目的地是queue,发布订阅模式中的目的地就是topic。

  5、生产者(Message Producer)和消费者(Message Consumer)对象由Session对象创建,用于发送和接收消息。

四、ActiveMQ

  上面说到JMS是java消息服务的技术规范,它制定了在整个消息服务提供过程中的所有数据结构和交互流程。而MQ则是消息队列服务,是面向消息中间件(MOM)的最终实现,是真正的服务提供者;MQ的实现可以基于JMS,也可以基于其他规范或标准。

ActiveMQ就是Apache组织的一个开源的消息中间件,它实现了JMS技术规范。

  1、ActiveMQ点对点模式

  下面的代码都是测试代码,消费者如果关闭连接,则只能消费一次消息,所以没有关闭。

public class MsgSender {

    //ActiveMq 的默认用户名
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
//ActiveMq 的默认登录密码
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
//ActiveMQ 的链接地址
private static final String BROKEN_URL = "tcp://127.0.0.1:61616";//ActiveMQConnection.DEFAULT_BROKER_URL; public static void main(String[] args) { //创建一个链接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
Connection connection = null;
Session session = null;
MessageProducer messageProducer = null;
try {
//从工厂中创建一个链接
connection= connectionFactory.createConnection();
//开启链接
connection.start();
//创建一个事务(这里通过参数可以设置事务的级别)
session = connection.createSession(true,Session.SESSION_TRANSACTED);
//创建一个消息队列
Queue queue = session.createQueue("myqueue");
//消息生产者
messageProducer = session.createProducer(queue);
int count = 0;
while(true){
Thread.sleep(1000); //创建一条消息
TextMessage msg = session.createTextMessage("生产消息"+count);
System.out.println("生产消息"+count++);
//发送消息
messageProducer.send(msg);
//提交事务
session.commit();
}
} catch (JMSException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
try {
if(connection != null){
connection.close();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
public class MsgReciver {

    private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;

    private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;

    private static final String BROKEN_URL = "tcp://127.0.0.1:61616";//ActiveMQConnection.DEFAULT_BROKER_URL;

    public static void main(String[] args) {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
try {
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("myqueue");
MessageConsumer consumer = null;
consumer = session.createConsumer(queue); MsgListener listener=new MsgListener();
consumer.setMessageListener(listener);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
public class MsgListener implements MessageListener {

    @Override
public void onMessage(Message msg) {
TextMessage tmsg = (TextMessage)msg;
try {
System.out.println("接收到的数据:"+tmsg.getText());
} catch (JMSException e) {
e.printStackTrace();
}
} }

  2、发布订阅模式

public class MsgSender {

    //ActiveMq 的默认用户名
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
//ActiveMq 的默认登录密码
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
//ActiveMQ 的链接地址
private static final String BROKEN_URL = "tcp://127.0.0.1:61616";//ActiveMQConnection.DEFAULT_BROKER_URL; public static void main(String[] args) { //创建一个链接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
Connection connection = null;
Session session = null;
MessageProducer messageProducer = null;
try {
//从工厂中创建一个链接
connection= connectionFactory.createConnection();
//开启链接
connection.start();
//创建一个事务(这里通过参数可以设置事务的级别)
session = connection.createSession(true,Session.SESSION_TRANSACTED);
//创建一个Topic
Topic myTopic = session.createTopic("mytopic");
//消息生产者
messageProducer = session.createProducer(myTopic);
int count = 0;
while(true){
Thread.sleep(10000);
//创建一条消息
TextMessage msg = session.createTextMessage("发布消息"+count);
System.out.println("发布消息"+count++);
//发送消息
messageProducer.send(msg);
//提交事务
session.commit();
}
} catch (JMSException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
try {
if(connection != null){
connection.close();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
public class MsgReciver {

    private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;

    private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;

    private static final String BROKEN_URL = "tcp://111.230.239.152:61616";//ActiveMQConnection.DEFAULT_BROKER_URL;

    public static void main(String[] args) {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
try {
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Topic myTopic = session.createTopic("mytopic");
MessageConsumer consumer = null;
consumer = session.createConsumer(myTopic);
MsgListener listener=new MsgListener();
consumer.setMessageListener(listener);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
public class MsgListener implements MessageListener {

    @Override
public void onMessage(Message msg) {
TextMessage tmsg = (TextMessage)msg;
try {
System.out.println("接收到的数据:"+tmsg.getText());
} catch (JMSException e) {
e.printStackTrace();
}
} }

  

  3、spring集成ActiveMQ

   引入jar包

 <!-- 整合activemq -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
activemq.brokerURL=tcp://127.0.0.1:61616

activemq.queue=myqueue

activemq.topic=mytopic
 <!-- 集成ActiveMQ -->
<!-- 配置能够产生connection的connectionfactory,由JMS对应的服务厂商提供 -->
<bean id="tagertConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<constructor-arg name="brokerURL" value="${activemq.brokerURL}"/>
</bean>
<!-- 配置spring管理真正connectionfactory的connectionfactory,相当于spring对connectionfactory的一层封装 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="tagertConnectionFactory"/>
</bean>
<!-- 配置生产者 -->
<!-- Spring使用JMS工具类,可以用来发送和接收消息 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这里是配置的spring用来管理connectionfactory的connectionfactory -->
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<!-- 配置destination -->
<!-- 队列目的地 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="${activemq.queue}"/>
</bean>
<!-- 话题目的地 -->
<bean id="itemAddTopic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="${activemq.topic}"/>
</bean> <!-- 配置监听器 -->
<bean id="myQueueListener" class="com.myproject.listener.MqQueueListener"/>
<bean id="mqTopicListener" class="com.myproject.listener.MqTopicListener"/>
<!-- 系统监听器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="queueDestination"/>
<property name="messageListener" ref="myQueueListener"/>
</bean>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="itemAddTopic"/>
<property name="messageListener" ref="mqTopicListener"/>
</bean>
public class MqQueueListener implements MessageListener {

    @Override
public void onMessage(Message message) {
TextMessage testMessage = (TextMessage)message;
try {
System.out.println("收到信息:"+testMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
public class MqTopicListener implements MessageListener {

    @Override
public void onMessage(Message message) {
TextMessage testMessage = (TextMessage)message;
try {
System.out.println("收到信息:"+testMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
} }
@Service
public class UserServiceImpl implements UserService { @Autowired
private UserMapper userMapper;
@Autowired
private RedisCacheUtil redisCacheUtil; @Autowired
private JmsTemplate jmsTemplate;
@Resource(name="itemAddTopic")
private Destination destination; @Override
public User getById(Map<String, Object> params) {
Integer userId = Integer.parseInt(params.get("id").toString());
User user = (User)redisCacheUtil.get(RedisKey.USER_BASIC_INFO+userId);
if(user == null ){
user = userMapper.selectByPrimaryKey(userId);
if(user != null ){
redisCacheUtil.set(RedisKey.USER_BASIC_INFO+userId, user);
}
}
ObjectMapper mapper = new ObjectMapper();
try {
final String userInfo = mapper.writeValueAsString(user);
//获取到用户后发送一个消息给其他模块
jmsTemplate.send(destination, new MessageCreator() { @Override
public Message createMessage(Session session) throws JMSException {
TextMessage msg = session.createTextMessage(userInfo);
return msg;
}
});
} catch (JsonProcessingException e) {
e.printStackTrace();
} return user;
}
}

  

jms和activemq的更多相关文章

  1. 深入浅出JMS(三)--ActiveMQ简单的HelloWorld实例

    第一篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了JMS的两种消息模型:点对点和发布订阅模型,以及消息被消费的两个方式:同步和异步,JMS编程模型的对象,最后说了JMS的优点. 第二篇博文深入 ...

  2. 【JMS】JMS之ActiveMQ的使用

    这篇文章主要是简单介绍一下JMS和ActiveMQ,以及使用ActiveMQ来写两个demo. 1. JMS是啥 百度百科的解释: JMS即Java消息服务(Java Message Service) ...

  3. ActiveMQ第二弹:使用Spring JMS与ActiveMQ通讯

    本文章的完整代码可从我的github中下载:https://github.com/huangbowen521/SpringJMSSample.git 上一篇文章中介绍了如何安装和运行ActiveMQ. ...

  4. Simple guide to Java Message Service (JMS) using ActiveMQ

    JMS let’s you send messages containing for example a String, array of bytes or a serializable Java o ...

  5. JMS and ActiveMQ first lesson(转)

    JMS and ActiveMQ first lesson -- jms基础概念和应用场景 2011-6-18 PM 9:30 主讲:kimmking <kimmking@163.com> ...

  6. spring集成JMS访问ActiveMQ

    首先我们搭建一个spring-mvc项目,项目可以参考:spring-mvc 学习笔记 步骤: 在pom.xml中加上需要的包 修改web.xml,增加IOC容器 spring配置文件applicat ...

  7. JMS之——ActiveMQ时抛出的错误Could not connect to broker URL-使用线程池解决高并发连接

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/69046395 解决使用activemq时抛出的异常:javax.j ms.JMSE ...

  8. 【ActiveMQ】Spring Jms集成ActiveMQ学习记录

    Spring Jms集成ActiveMQ学习记录. 引入依赖包 无论生产者还是消费者均引入这些包: <properties> <spring.version>3.0.5.REL ...

  9. 深入浅出 JMS(三) - ActiveMQ 安全机制

    深入浅出 JMS(三) - ActiveMQ 安全机制 一.认证 认证(Authentication):验证某个实体或者用户是否有权限访问受保护资源. MQ 提供两种插件用于权限认证: (一).Sim ...

  10. 深入浅出 JMS(四) - ActiveMQ 消息存储

    深入浅出 JMS(四) - ActiveMQ 消息存储 一.消息的存储方式 ActiveMQ 支持 JMS 规范中的持久化消息与非持久化消息 持久化消息通常用于不管是否消费者在线,它们都会保证消息会被 ...

随机推荐

  1. HTML5-Video视频-基础篇

    展示视频 视频 <video width=" controls="controls"> <source src="movie.mp4" ...

  2. JavaScript——JS屏蔽F12和右键

    键盘表 来源:http://www.phpweblog.net/kiyone/archive/2007/04/19/1138.html 通过onkeydowm监听键盘按下事件,并修改键盘码 //禁止F ...

  3. DRF 版本和认证

    Django Rest Framework 版本控制组件 DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢~~大家都知道我们开发项目是有多个版本的~~ 当我们 ...

  4. Codeforces510 D. Fox And Jumping

    Codeforces题号:#510D 出处: Codeforces 主要算法:map+DP 难度:4.6 思路分析: 题意:给出n张卡片,分别有l[i]和c[i].在一条无限长的纸带上,你可以选择花c ...

  5. 南理第八届校赛同步赛-C count_prime//容斥原理

    大致思路就是先求出n的质因数假设是a1-an,然后在1-a的区间里面查找至少能整除{a1,a2...an}中一个元素的数有多少个,对1-b也做相同的处理,而找出来的元素肯定是与n不互质的,那么把区间的 ...

  6. Spring学习记录

    Java类定义配置@Configuration //标记为配置类@ComponentScan //标记为扫描当前包及子包所有标记为@Component的类@ComponentScan(basePack ...

  7. 【BZOJ3174】[TJOI2013]拯救小矮人(贪心,动态规划)

    [BZOJ3174][TJOI2013]拯救小矮人(贪心,动态规划) 题面 BZOJ 洛谷 题解 我们定义一个小矮人的\(A_i+B_i\)为它的逃跑能力. 我们发现,如果有两个小矮人\(x,y\), ...

  8. AES解密后多了\0

    AES加密解密之后发现多了几个空格,不知道原因.在调试时发现多了\0这种东西 不知道为什么会多这些.后来.replace("\0","")这样做了事

  9. hdu 1238 Substrings(kmp+暴力枚举)

    Problem Description You are given a number of case-sensitive strings of alphabetic characters, find ...

  10. 解决使用jedis连接是报DENIED Redis is running in protected mode错误

    DENIED Redis is running in protected mode because protected mode is enabled, no bind address was spe ...