一、安装activemq

下载地址:https://archive.apache.org/dist/activemq/5.13.0/apache-activemq-5.13.0-bin.zip

下载完后如果是64位操作系统打开~\apache-activemq-5.13.0\bin\win64目录下的activemq.bat即可,如果是32位的打开~\apache-activemq-5.13.0\bin\win32目录下的activemq.bat就可以了。

打开activemq的管理地址http://localhost:8161/admin/,用户名和密码都是admin,出现以下界面说明activemq已经正常运行。

二、创建maven项目,pom.xml中添加activemq的jar包依赖:

    <dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.13.0</version>
</dependency>

三、activemq连接池的实现

  1、创建连接池接口ConnectionPool

package com.guods.mymq.activemq;

import javax.jms.Connection;
import javax.jms.JMSException; /**
* jms连接池接口
* @author guods
*
*/
public interface ConnectionPool { Connection getConnection() throws JMSException;
void releaseConnection(Connection connection);
}

  2、连接池实现ConnectionPoolImpl

    创建初始连接,并把连接存到链表,使用的时候从链表中获取连接。

package com.guods.mymq.activemq;

import java.util.LinkedList;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException; import org.apache.activemq.ActiveMQConnectionFactory; /**
* jms连接池实现
* @author guods
*
*/
public class ConnectionPoolImpl implements ConnectionPool { //连接用户名
private static final String USERNAME = "admin";
//连接密码
private static final String PASSWORD = "admin";
//连接地址
private static final String BROKEURL = "tcp://localhost:61616";
//初始连接数
private static final int INIT_SIZE = 2;
//最大连接数
private static final int MAX_SIZE = 5;
//当前存在的连接总数,包括:正在使用的连接 + connections列表中的连接
private int poolSize = 0; //创建连接工厂
private ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);
//存放空闲connection的链表
private LinkedList<Connection> connections = new LinkedList<Connection>(); public ConnectionPoolImpl() {
initConnections();
}
/**
* 初始化连接,生成初始连接数
*/
private void initConnections() {
for (int i = 0; i < INIT_SIZE; i++) {
try {
connections.add(createConnection());
} catch (JMSException e) {
e.printStackTrace();
}
}
} /**
* 添加连接,每增加一个connection,poolSize加1
* @throws JMSException
*/
private synchronized Connection createConnection() throws JMSException {
Connection newConnection = connectionFactory.createConnection();
newConnection.start();
poolSize++;
return newConnection;
}
/**
* 删除连接,每删除一个connection,poolSize减1
* @param connection
* @throws JMSException
*/
private synchronized void delConnection() throws JMSException {
Connection connection = connections.removeFirst();
if (connection != null) {
connection.close();
poolSize--;
}
}
/**
* 从连接池获取connection
* @throws JMSException
*/
public synchronized Connection getConnection() throws JMSException {
int i = 0;
while (true) {
//3次获取连接失败,抛超时异常
if (i == 3) {
throw new JMSException("Get connection timeout !");
}
//连接池有连接,直接取一个返回
if (connections.size() > 0) {
return connections.removeFirst();
}
//连接池空,如果连接数没到最大,创建一个连接返回
if (poolSize < MAX_SIZE) {
try {
return createConnection();
} catch (JMSException e) {
}
}
//连接池空,并且连接达到最大数,等1秒再试尝试获取连接
try {
Thread.sleep(1000);
i++;
} catch (InterruptedException e) {
}
}
}
/**
* 释放连接,连接用完后放回队列
*/
public synchronized void releaseConnection(Connection connection) {
connections.add(connection);
} }

 四、创建jms模板

  beginSession方法从连接池获取连接,创建session。

  endSession方法提交session,并把连接交还给连接池。

  execute方法整合了beginSession和endSession两个模板方法,中间执行抽象方法action中的内容。

  action在子类中实现业务操作,如创建队列、生产消息、消费消息等。

package com.guods.mymq.activemq;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Session; /**
* 模板模式,创建JMS模板
* @author guods
*
*/
public abstract class JmsTemplate { private ConnectionPool connectionPool;
private Connection connection;
private Session session; public JmsTemplate(ConnectionPool connectionPool) {
super();
this.connectionPool = connectionPool;
} public abstract Object action(Session session) throws JMSException; public Object execute() throws JMSException{
//获取连接,开启session
beginSession();
//处理事务
Object object = action(session);
//关闭session,释放连接
endSession();
return object;
} /**
* 从连接池获取connection,创建session
* @throws JMSException
*/
private void beginSession() throws JMSException{
connection = connectionPool.getConnection();
session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
} /**
* 提交事务,关闭session,释放connection
* @throws JMSException
*/
private void endSession() throws JMSException{
session.commit();
session.close();
connectionPool.releaseConnection(connection);
}
}

五、实现activemq的各种业务操作

package com.guods.mymq.activemq;

import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage; /**
* activemq的各种业务操作
* @author guods
*
*/
public class JmsAction { private ConnectionPool connectionPool; public JmsAction(ConnectionPool connectionPool) {
super();
this.connectionPool = connectionPool;
} /**
* 创建消息队列
* @param queueName
* @return
* @throws JMSException
*/
public Queue createQueue(final String queueName) throws JMSException { return (Queue) new JmsTemplate(connectionPool) { @Override
public Object action(Session session) {
try {
return session.createQueue(queueName);
} catch (JMSException e) {
return null;
}
}
}.execute();
}; /**
* 发送p2p消息
* @param queue
* @param message
* @throws JMSException
*/
public void produceP2pMessage(final Queue queue, final String message) throws JMSException{
new JmsTemplate(connectionPool) { @Override
public Object action(Session session) throws JMSException {
MessageProducer messageProducer = session.createProducer(queue);
TextMessage textMessage = session.createTextMessage(message);
messageProducer.send(queue, textMessage);
return null;
}
}.execute();
} /**
* 消费一条p2p消息
* @param queue
* @return
* @throws JMSException
*/
public String consumP2pMessage(final Queue queue) throws JMSException{
return (String) new JmsTemplate(connectionPool) { @Override
public Object action(Session session) throws JMSException {
MessageConsumer createConsumer = session.createConsumer(queue);
TextMessage textMessage = (TextMessage) createConsumer.receive(10000);
if (textMessage == null) {
return null;
}
return textMessage.getText();
}
}.execute();
} }

六、测试

  1、生产者生产消息

package com.guods.mymq.activemq;

import javax.jms.JMSException;
import javax.jms.Queue; public class JmsProducer { private static ConnectionPool connectionPool = new ConnectionPoolImpl();
private static JmsAction jmsAction = new JmsAction(connectionPool); public static void main(String[] args) throws JMSException {
//创建队列
Queue queue = jmsAction.createQueue("MyQueue");
//生产消息
for (int i = 0; i < 5; i++) {
String message = "第" + i + "条消息!";
jmsAction.produceP2pMessage(queue, message);
System.out.println("生产消息:" + message);
}
}
}

  2、消费者消费消息

package com.guods.mymq.activemq;

import javax.jms.JMSException;
import javax.jms.Queue; public class JmsConsumer { private static ConnectionPool connectionPool = new ConnectionPoolImpl();
private static JmsAction jmsAction = new JmsAction(connectionPool); public static void main(String[] args) throws JMSException {
//创建队列
Queue queue = jmsAction.createQueue("MyQueue");
//消费消息
while (true) {
String message = jmsAction.consumP2pMessage(queue);
if (message != null) {
System.out.println("消费消息:" + message);
}
}
}
}

git源码:https://github.com/dongsheng824/mymq.git

ActiveMQ学习心得:连接池的简单实现和模板模式的应用的更多相关文章

  1. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  2. Okhttp之连接池ConnectionPool简单分析(一)

    开篇声明:由于本篇博文用到的一些观点或者结论在之前的博文中都已经分析过,所以本篇博文直接拿来用,建议读此博文的Monkey们按照下面的顺序读一下博主以下博文,以便于对此篇博文的理解: <Okht ...

  3. Java的JDBC原生态学习以及连接池的用法

    JDBC是什么 JDBC(Java Data Base Connectivity)是Java访问数据库的桥梁,但它只是接口规范,具体实现是各数据库厂商提供的驱动程序(Driver). 应用程序.JDB ...

  4. java 连接池的简单实现

    最近一个项目中需要自己写个连接池, 写了一个下午,挺辛苦的,但不知道会不会出问题, 所以,贴到博客上,欢迎各路大神指点 1. 配置信息: /** * */ package cn.mjorcen.db. ...

  5. 阿里巴巴连接池Druid简单使用

    Druid参考:https://github.com/alibaba/druid 偶尔的机会解释Druid连接池,后起之秀,但是评价不错,另外由于是阿里淘宝使用过的所以还是蛮看好的. Druid集连接 ...

  6. MySQL_(Java)【连接池】简单在JDBCUtils.java中创建连接池

    MySQL_(Java)[事物操作]使用JDBC模拟银行转账向数据库发起修改请求 传送门 MySQL_(Java)[连接池]使用DBCP简单模拟银行转账事物 传送门 Java应用程序访问数据库的过程: ...

  7. nodejs的mysql模块学习(十)连接池集群配置选项

    连接池集群选项 canRetry : 如果true ,连接池集群会在连接失败时尝试连接 默认true removeNodeErrorCount : 如果连接失败,节点的errCount增加.当erro ...

  8. nodejs的mysql模块学习(九)连接池集群

    连接池集群 连接池集群可以提供多个主机连接 创建连接池集群 //创建连接池集群 var poolCluster = mysql.createPoolCluster(); //添加配置 config是一 ...

  9. nodejs的mysql模块学习(七)连接池事件

    连接池事件 connection 当建立连接的时候就会触发 pool.on('connection' function(connection){ connection.query('SET SESSI ...

随机推荐

  1. 读书笔记 effective c++ Item 31 把文件之间的编译依赖降到最低

    1. 牵一发而动全身 现在开始进入你的C++程序,你对你的类实现做了一个很小的改动.注意,不是接口,只是实现:一个私有的stuff.然后你需要rebuild你的程序,计算着这个build应该几秒钟就足 ...

  2. Java 数值类型以及计算

    前段时候写了一个对外提供的接口,其中有一个数值校验的计算.在测试的过程中发现5.6-1.6 != 4,在反复的测试过程中发现double类型的数值为有精度丢失的现象,看来还是基础知识不牢固,所以就在网 ...

  3. Spring Boot启动过程(五):Springboot内嵌Tomcat对象的start

    标题和上一篇很像,所以特别强调一下,这个是Tomcat对象的. 从TomcatEmbeddedServletContainer的this.tomcat.start()开始,主要是利用Lifecycle ...

  4. web第十天总结

    今天进入web学习第十天,学习了xml序列化,servlet,其他的想不起来了,回顾以前的java基础面向对象,多态,继承.封装,但是还不是很理解.对于map,list,set更是理解不透,2011年 ...

  5. Intellij Idea自动加载改动文件和自动自动热部署加载

    1:准备原料 我的Intellij Idea的版本是15. 之后tomcat自动加载修,你只需要在浏览器刷新一下页面即可. ************************************** ...

  6. Python Number(数字)

    ---Number类型的细节,其包含的基本数字类型 ---Number基本数字类型之间的数值转换 ---Number上面的数学函数,有些可以直接调用,有些需要导入库 参见http://www.runo ...

  7. SQL AlawaysOn 之四:故障转移集群

    声明,故障转移集群,仅安装在SQL服务器中,域服务器不能和SQL服务器一起加入集群. 1.添加故障转移集群,下一步 2.安装 3.在域控制服务器上的管理工具里打开故不障转移集群管理器,选择创建集群 4 ...

  8. ioS开发之CoreLocation(GPS定位)

    1.概述 在iOS开发中,要想加入地图和定位功能这2大功能,必须基于2个框架进行开发 (1)Map Kit :用于地图展示 (2)Core Location :用于地理定位 2个热门专业术语: LBS ...

  9. Android -- onMeasure()源码分析

    1,作为自定义控件最重要的三个方法之一,onMeasure()可以说是我们研究的重点,今天我们更详细的来研究一下View的onMeasure()方法和ViewGroup的onMeasure()方法 2 ...

  10. spring security 3.x 多页面登录配置入门教程

    最近在最shiro的多入口登录,搞了好久,就把spring security拿出来再炒一下,这是我以前在csdn写过的一篇博客. spring security 是一个权限控制的框架.可以很方便地实现 ...