ActiveMQ——笔记

AMQP介绍:

       AMQP(advanced message queuing protocol)是一个提供统一消息服务的应用层标准协议,基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。(总结,一个应用层的数据传输协议)。

       AMQP的定义:Wire-protocol。可跨语言,并提供了5种消息模型(direct、fanout、topic、headers、system)、由于是属于数据传输协议和跨语言的原因,因此只支持byte[](即二进制数据)。综合评价,AMPQ的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全

ActiveMQ介绍:

       ActiveMQ是Apache出品,流行的、能力强劲的开源消息总线。ActiveMQ是一个完全支持的JMS1.1和J2EE1.4 规范的 JMS Provider 实现

ActiveMQ特性:

         1、支持多语言(Java、C、C++、C#、Ruby、Perl、Python、PHP等)

         2、支持多总应用协议(OpenWire、Stomp、REST、WS Notification、XMPP、AMQP)

         3、完全支持JMS1.1和J2EE1.4规范(持久化、XA消息、事务)

         4、虚拟主题、组合目的、镜像队列

ActiveMQ安装:

         1.windows:

                   (1)、下载对应系统的安装包,并解压。

                   (2)、进入解压后的ActiveMQ根目录下的bin目录中,选择对应32或64位系统中。

                 (3)、(建议使用管理员方式运行)运行InstallService.bat文件进行服务安装(建议)或activemq.bat文件即可。(注:使用服务启动方式,在服务安装完成后需要在dos命令中输入net start ActiveMQ(服务名) 命令或直接在服务窗口中启动该服务,默认安装的服务名为ActiveMQ)

               (4)、在浏览器中输入127.0.0.1:8161即可访问。(注:ActiveMQ:浏览器访问的默认端口号为8161,登陆账号与密码都为admin)

          2.linux:

                   (1)、下载对应系统的安装包,并解压。

                   (2)、进入解压后的ActiveMQ根目录下的bin目录中

                   (3)、在终端中输入 ./activemq start 启动;./activemq stop 停止(注:具体访问windows安装(4)步骤)

JMS队列模式演示(p2p):

       1.创建一个maven项目,并导包。

<dependency>
	<groupId>org.apache.activemq</groupId>
	<artifactId>activemq-all</artifactId>
	<version>5.9.1</version>
</dependency>
       1、示例1——生产者
package jms.activemq.queue;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * 生产者
 */
public class AppProducers {
	//连接路径,61616:为ActiveMQ默认端口
    final static String url = "tcp://127.0.0.1:61616";
    //创建的目标的队列名
    final static String queueName = "queue-test";
	public static void main(String[] args) throws JMSException {
		//创建一个连接工厂
		ConnectionFactory factory = new ActiveMQConnectionFactory(url);
		//创建一个连接
		Connection connection = factory.createConnection();
		//启动连接
		connection.start();
		//创建一个会话,第一个参数表示是否在事务中处理(这里是不在事务中处理),第二个参数表示是应答模式(这里是自动应答)
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		//创建一个目标队列
		Destination destination = session.createQueue(queueName);
		//创建一个生产者,并指定消息的发送目标
		MessageProducer producer = session.createProducer(destination);
		//发送一百个消息给ActiveMQ
		for(int i = 0; i<100; i++){
			//创建一个消息
			TextMessage message = session.createTextMessage("我就看看:"+i);
			//发送消息
			producer.send(message);
		}
		//用完之后,记得关闭连接噢!很重要的
        connection.close();
	}
}

运行结果:

    2、示例2——消费者(注意:消费的是示例1发送的消息)

          

package jms.activemq.queue;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * 消费者
 */
public class AppConsumer {
	//连接路径,61616:为ActiveMQ默认端口
    final static String url = "tcp://127.0.0.1:61616";
    //创建的目标的队列名
    final static String queueName = "queue-test";
	public static void main(String[] args) throws Exception {
		//创建一个连接工厂
		ConnectionFactory factory = new ActiveMQConnectionFactory(url);
		//创建一个连接
		Connection connection = factory.createConnection();
		//启动连接
		connection.start();
		//创建一个会话,第一个参数表示是否在事务中处理(这里是不在事务中处理),第二个参数表示是应答模式(这里是自动应答)
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		//创建一个目标队列
		Destination destination = session.createQueue(queueName);
		//创建一个消费者,并指定消息的发送目标
		MessageConsumer consumer = session.createConsumer(destination);
		//创建一个消息监听器,用以监听发送过来的消息
		consumer.setMessageListener(new MessageListener() {
		    //接收消息时的处理方法
			public void onMessage(Message message) {
				TextMessage textMessage = (TextMessage)message;
				try {
					System.out.println(textMessage.getText());
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
		});
        //温馨提示:这里不能关闭连接噢,否者事件处理器无法监听消息,因此只能在关闭应用时才能关闭连接
	}
}

JMS主题模式演示(注意:一定要先订阅者,在发布者,不然无法获取订阅之前发送到该主题的消息):

              订阅者:

package jms.activemq.topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * 订阅者
 */
public class AppConsumer {
	//连接路径,61616:为ActiveMQ默认端口
    final static String url = "tcp://127.0.0.1:61616";
    //创建的目标的主题名
    final static String topicName = "topic-test";
	public static void main(String[] args) throws Exception {
		//创建一个连接工厂
		ConnectionFactory factory = new ActiveMQConnectionFactory(url);
		//创建一个连接
		Connection connection = factory.createConnection();
		//启动连接
		connection.start();
		//创建一个会话,第一个参数表示是否在事务中处理(这里是不在事务中处理),第二个参数表示是应答模式(这里是自动应答)
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		//创建一个目标主题
		Destination destination = session.createTopic(topicName);
		//创建一个订阅者,并指定消息的发送目标
		MessageConsumer consumer = session.createConsumer(destination);
		//创建一个消息监听器,用以监听发送过来的消息
		consumer.setMessageListener(new MessageListener() {
		    //接收消息时的处理方法
			public void onMessage(Message message) {
				TextMessage textMessage = (TextMessage)message;
				try {
					System.out.println(textMessage.getText());
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
		});
        //温馨提示:这里不能关闭连接噢,否者事件处理器无法监听消息,因此只能在关闭应用时才能关闭连接
	}
}

            发布者:

package jms.activemq.topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * 发布者
 */
public class AppProducers {
	//连接路径,61616:为ActiveMQ默认端口
    final static String url = "tcp://127.0.0.1:61616";
    //创建的目标的主题名
    final static String topicName = "topic-test";
	public static void main(String[] args) throws JMSException {
		//创建一个连接工厂
		ConnectionFactory factory = new ActiveMQConnectionFactory(url);
		//创建一个连接
		Connection connection = factory.createConnection();
		//启动连接
		connection.start();
		//创建一个会话,第一个参数表示是否在事务中处理(这里是不在事务中处理),第二个参数表示是应答模式(这里是自动应答)
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		//创建一个目标主题
		Destination destination = session.createTopic(topicName);
		//创建一个发布者,并指定消息的发送目标
		MessageProducer producer = session.createProducer(destination);
		//发送一百个消息给ActiveMQ
		for(int i = 0; i<100; i++){
			//创建一个消息
			TextMessage message = session.createTextMessage("我就看看:"+i);
			//发送消息
			producer.send(message);
			System.out.println(message.getText());
		}
		//用完之后,记得关闭连接噢!很重要的
        connection.close();
	}
}

Spring集成JMS——队列示例:

    生产者:

        1、使用在Spring配置文件中将ActiveMQ加入Spring容器中管理(这里先抽调出公共配置,减少配置消费者时重复配置)。

<?xml version="1.0" encoding="UTF-8"?>
<!-- 这是一段公共的配置 -->
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 激活在spring容器中注册过的bean -->
	<context:annotation-config/>
	<!-- ActiveMQ提供的ConnertionFactory -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
	    <property name="brokerURL" value="tcp://127.0.0.1:61616"></property>
	</bean>
	<!-- Spring jms提供的提供的连接池 -->
	<bean id="connertionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
	    <property name="targetConnectionFactory"  ref="targetConnectionFactory"/>
	</bean>
	<!-- 一个队列目的地,点对点的 -->
	<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
	    <!-- 构造注入,spring-queue目的地名 -->
	    <constructor-arg value="spring-queue"/>
	</bean>
</beans>

           2、开始配置生产者独有的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 引入一段公共的配置 -->
	<import resource="common.xml"/>
	<!-- 使用spring提供的消息发送模板 -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
	    <!-- 为该模板绑定连接 -->
	    <property name="connectionFactory" ref="connertionFactory"></property>
	</bean>
	<!-- 将ProducerServiceImpl填入Spring容器中进行管理 -->
	<bean class="spring.jms.queue.producer.ProducerSrviceImpl"></bean>
</beans>

          3、创建上述配置文件中的生产者发送消息接口及实现类(ProducerSrviceImpl)。

package spring.jms.queue.producer;

public interface ProducerService {
    void sendMessage(String message);
}
package spring.jms.queue.producer;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class ProducerSrviceImpl implements ProducerService {
    
	@Autowired
	JmsTemplate jmsTemplate;
	
	@Autowired
	@Qualifier("queueDestination")//将队列目标注入进来,因为可以创建多个,所以使用byName注入
	Destination destination;
	
	public void sendMessage(final String message) {
		//使用jmsTemplate模板发送消息
		jmsTemplate.send(destination,new MessageCreator() {	
			//创建一个消息
			public Message createMessage(Session session) throws JMSException {
				TextMessage textMessage = session.createTextMessage(message);
				System.out.println("发送消息:"+textMessage.getText());
				return textMessage;
			}
		});

	}
}

        4、创建生产者的启动类:

package spring.jms.queue.producer;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *生产者——队列——启动类
 */
public class AppProducer {
    public static void main(String[] args){
    	ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:queue/producer.xml");
    	ProducerService producerService = ac.getBean(ProducerService.class);
    	for(int i = 0;i < 100;i++ ){
    		producerService.sendMessage("test-spring-jms: "+i);
    	}
    	ac.close();
    }
}

    消费者:

        1、将ActiveMQ加入到Spring容器中进行配置(这里引入了一段公共的配置,上面提到了的common.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" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 引入一段公共的配置 -->
	<import resource="common.xml"/>
	<!-- 配置消息监听器 -->
	<bean id="consumerMessageListener" class="spring.jms.queue.consumer.ConsumerMessageListener"/>
	<!-- 配置消息容器,需要指定连接,目标,监听器等 -->
	<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
	    <property name="connectionFactory" ref="connertionFactory"></property>
	    <property name="destination" ref="queueDestination"></property>
	    <property name="messageListener" ref="consumerMessageListener"></property>
	</bean>
	
</beans>

        2、创建上述配置文件中的消息监听器(需要实现MessageListener接口)

package spring.jms.queue.consumer;


import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
 * 创建一个消息监听者,需要实现MessageListener接口
 */
public class ConsumerMessageListener implements MessageListener {
    //处理监听到的消息的方法
	public void onMessage(Message message) {
		TextMessage textMessage = (TextMessage)message;
		try {
			System.out.println(textMessage.getText());
		} catch (JMSException e) {
			e.printStackTrace();
		}


	}


}

        3、创建消费者启动类:

package spring.jms.queue.consumer;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 *消费者——队列——启动类
 */
public class AppConsumer {
    public static void main(String[] args){
    	ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:queue/consumer.xml");
    }
}

Spring集成JMS——主题示例(与上述Spring集成JMS——队列模式类似):

    发布者:

        1.同上,创建一段公共的配置,并配置发布者独有的配置。

<?xml version="1.0" encoding="UTF-8"?>
<!-- 这是一段公共的配置 -->
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 激活在spring容器中注册过的bean -->
	<context:annotation-config/>
	<!-- ActiveMQ提供的ConnertionFactory -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
	    <property name="brokerURL" value="tcp://127.0.0.1:61616"></property>
	</bean>
	<!-- Spring jms提供的提供的连接池 -->
	<bean id="connertionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
	    <property name="targetConnectionFactory"  ref="targetConnectionFactory"/>
	</bean>
	<!-- 一个队列目的地,点对点的 -->
	<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
	    <!-- 构造注入,spring-queue目的地名 -->
	    <constructor-arg value="spring-topic"/>
	</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 引入一段公共的配置 -->
	<import resource="common.xml"/>
	<!-- 使用spring提供的消息发送模板 -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
	    <!-- 为该模板绑定连接 -->
	    <property name="connectionFactory" ref="connertionFactory"></property>
	</bean>
	<!-- 将ProducerServiceImpl填入Spring容器中进行管理 -->
	<bean class="spring.jms.topic.producer.ProducerSrviceImpl"></bean>
</beans>

         2、创建上述配置文件中的发布者发送消息的接口及实现类:

package spring.jms.topic.producer;

public interface ProducerService {
    void sendMessage(String message);
}
package spring.jms.topic.producer;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class ProducerSrviceImpl implements ProducerService {
    
	@Autowired
	JmsTemplate jmsTemplate;
	
	@Autowired
	@Qualifier("topicDestination")//将主题目标注入进来,因为可以创建多个,所以使用byName注入
	Destination destination;
	
	public void sendMessage(final String message) {
		//使用jmsTemplate模板发送消息
		jmsTemplate.send(destination,new MessageCreator() {	
			//创建一个消息
			public Message createMessage(Session session) throws JMSException {
				TextMessage textMessage = session.createTextMessage(message);
				System.out.println("发送消息:"+textMessage.getText());
				return textMessage;
			}
		});

	}

}

        3、创建移动类:

package spring.jms.topic.producer;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *发布者——主题——启动类
 */
public class AppProducer {
    public static void main(String[] args){
    	ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:topic/producer.xml");
    	ProducerService producerService = ac.getBean(ProducerService.class);
    	for(int i = 0;i < 100;i++ ){
    		producerService.sendMessage("test-spring-jms: "+i);
    	}
    	ac.close();
    }
}

    订阅者:

          1、将ActiveMQ加载Spring容器中管理(同样引入了公共的配置):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 引入一段公共的配置 -->
	<import resource="common.xml"/>
	<!-- 配置消息监听器 -->
	<bean id="consumerMessageListener" class="spring.jms.queue.consumer.ConsumerMessageListener"/>
	<!-- 配置消息容器,需要指定连接,目标,监听器等 -->
	<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
	    <property name="connectionFactory" ref="connertionFactory"></property>
	    <property name="destination" ref="topicDestination"></property>
	    <property name="messageListener" ref="consumerMessageListener"></property>
	</bean>
	
</beans>

        2、创建上述配置文件中的消息监听器(MessageListener):

package spring.jms.topic.consumer;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
 * 创建一个消息监听者,需要实现MessageListener接口
 */
public class ConsumerMessageListener implements MessageListener {
    //处理监听到的消息的方法
	public void onMessage(Message message) {
		TextMessage textMessage = (TextMessage)message;
		try {
			System.out.println(textMessage.getText());
		} catch (JMSException e) {
			e.printStackTrace();
		}

	}

}

        3、创建订阅者启动类:

package spring.jms.topic.consumer;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 *订阅者——主题——启动类
 */
public class AppConsumer {
    public static void main(String[] args){
    	ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:topic/consumer.xml");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38976805/article/details/79349293