Java工具篇之apache池化技术

简介: 羽化而登仙,池化而提效 本篇文章我们的研究专题是池化技术, 其实所谓池化可以简单理解为缓存。将那些创建比较耗时的对象,缓存起来,放到一个池子里。比如数据库连接池,线程池,字符串常量池。这个技术常用于框架类设计。本文教你基于Apache-commons-pool2快速实现一个常量池的设计。
本篇文章我们的研究专题是池化技术, 其实所谓池化可以简单理解为缓存。将那些创建比较耗时的对象,缓存起来,放到一个池子里。
比如数据库连接池,线程池,字符串常量池。这个技术常用于框架类设计。本文教你基于Apache-commons-pool2快速实现一个常量池的设计。

一、Pool2 四大件

1.1 新建资源

1.2 回收资源

二、数据库连接池实战

我们利用Common Pool2工具 可以使用很少的代码就实现了池化的能力。

2.2 构建连接工厂

可以看到核心方法非常少,开发者只用实现很少方法即可

  1. makeObject 创建资源
  2. activateObject 资源被激活时候调用
  3. passivateObject 资源在回收时候调用
  4. validateObject 当配置了资源检查时候会在创建和回收时候调用
  5. destroyObject 资源在销毁时候调用
public class PooledConnectFactory implements PooledObjectFactory<Connection> {


    /**
     * 数据库连接
     */
    private final String url;

    /**
     * 用户名
     */
    private final String userName;

    /**
     * 数据密码
     */
    private final String password;

    public PooledConnectFactory(String url, String userName, String password) {
        this.url = url;
        this.userName = userName;
        this.password = password;
    }

    /**
     * 对象被激活后,会进行调用
     *
     * @param pooledObject a {@code PooledObject} wrapping the instance to be activated
     */
    @Override
    public void activateObject(PooledObject<Connection> pooledObject) throws Exception {
    }

    /**
     * 销毁数据库连接
     *
     * @param pooledObject a {@code PooledObject} wrapping the instance to be destroyed
     * @throws Exception 异常
     */
    @Override
    public void destroyObject(PooledObject<Connection> pooledObject) throws Exception {
        Connection connection = pooledObject.getObject();
        connection.close();
    }

    /**
     * 创建一个数据库连接
     *
     * @return 数据库连接的池对象包装
     * @throws Exception 异常
     */
    @Override
    public PooledObject<Connection> makeObject() throws Exception {
        Connection connection = DriverManager.getConnection(this.url, this.userName, this.password);
        return new DefaultPooledObject<>(connection);
    }

    /**
     * 回收资源时候进行调用
     * @param pooledObject a {@code PooledObject} wrapping the instance to be passivated
     *
     * @throws Exception
     */
    @Override
    public void passivateObject(PooledObject<Connection> pooledObject) throws Exception {

    }

    @Override
    @SneakyThrows
    public boolean validateObject(PooledObject<Connection> pooledObject) {
        Connection connection = pooledObject.getObject();
        // 如果连接关闭说明已经失效就返回false告诉池子,已经失效,会自动移除
        return !connection.isClosed();
    }
}

2.3 连接池演示

    @Test
    @DisplayName("验证回收对象")
    public void testReturn()throws Exception{
        // 1. 构建一个数据连接池化工厂
        String dbUrl = "jdbc:mysql://127.0.0.1:3306/test";
        String user = "root";
        String pass = "123456";
        PooledConnectFactory pooledConnectFactory = new PooledConnectFactory(dbUrl, user, pass);

        // 2. 给池子添加支持的配置信息
        GenericObjectPoolConfig<Connection> config = new GenericObjectPoolConfig<Connection>();
        // 2.1 最大池化对象数量
        config.setMaxTotal(5);
        // 2.2 最大空闲池化对象数量
        config.setMaxIdle(2);
        // 2.3 最小空闲池化对象数量
        config.setMinIdle(2);
        // 2.4 间隔多久检查一次池化对象状态,驱逐空闲对象,检查最小空闲数量小于就创建
        config.setTimeBetweenEvictionRuns(Duration.ofSeconds(5));
        // 2.5 阻塞就报错
        config.setBlockWhenExhausted(true);
        // 2.6 最大等待时长超过5秒就报错,如果不配置一直进行等待
        config.setMaxWait(Duration.ofSeconds(5));
        // 2.7 是否开启jmx监控,默认开启
        config.setJmxEnabled(true);
        // 2.8 一定要符合命名规则,否则无效
        config.setJmxNameBase("org.apache.commons.pool2:type=MysqlConnObjectPool,name=ConnectJmxNameBase");
        // 生成数据库连接池
        // 连接池配置最大5个连接setMaxTotal(5),但是获取6次,那么有一次获取不到就会阻塞setBlockWhenExhausted(true),
        // 当等待了10秒setMaxWait(Duration.ofSeconds(10))还是获取不到。就直接报错
        try (GenericObjectPool<Connection> connPool = new GenericObjectPool<>(pooledConnectFactory, config)) {
            for (int i = 1; i <= 7; i++) {
                Connection connection = connPool.borrowObject();
                Statement statement = connection.createStatement();
                ResultSet show_tables = statement.executeQuery("show tables");
                printRows("Connect-" + i + ">", show_tables);
                connPool.returnObject(connection);
            }
        }
    }

甚至还能配置支持jmx管理。非常的简单和方便。

相关文章
|
1天前
|
SQL Java 数据库连接
Java从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
ava从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
|
1天前
|
设计模式 存储 前端开发
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
|
1天前
|
Java API
Java从入门到精通:2.1.5深入学习Java核心技术之文件操作
Java从入门到精通:2.1.5深入学习Java核心技术之文件操作
|
1天前
|
并行计算 算法 安全
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
|
5天前
|
Java API Apache
ZooKeeper【基础 03】Java 客户端 Apache Curator 基础 API 使用举例(含源代码)
【4月更文挑战第11天】ZooKeeper【基础 03】Java 客户端 Apache Curator 基础 API 使用举例(含源代码)
23 11
|
7天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
8天前
|
存储 数据可视化 安全
Java全套智慧校园系统源码springboot+elmentui +Quartz可视化校园管理平台系统源码 建设智慧校园的5大关键技术
智慧校园指的是以物联网为基础的智慧化的校园工作、学习和生活一体化环境,这个一体化环境以各种应用服务系统为载体,将教学、科研、管理和校园生活进行充分融合。无处不在的网络学习、融合创新的网络科研、透明高效的校务治理、丰富多彩的校园文化、方便周到的校园生活。简而言之,“要做一个安全、稳定、环保、节能的校园。
33 6
|
8天前
|
消息中间件 存储 Java
深度探索:使用Apache Kafka构建高效Java消息队列处理系统
【4月更文挑战第17天】本文介绍了在Java环境下使用Apache Kafka进行消息队列处理的方法。Kafka是一个分布式流处理平台,采用发布/订阅模型,支持高效的消息生产和消费。文章详细讲解了Kafka的核心概念,包括主题、生产者和消费者,以及消息的存储和消费流程。此外,还展示了Java代码示例,说明如何创建生产者和消费者。最后,讨论了在高并发场景下的优化策略,如分区、消息压缩和批处理。通过理解和应用这些策略,可以构建高性能的消息系统。
|
8天前
|
监控 前端开发 算法
Java技术体系
Java技术体系(韩顺平老师整理)
9 0
|
19天前
|
存储 安全 Java
Java中实现高效的字符串拼接技术
【4月更文挑战第6天】在Java编程中,字符串拼接是一个常见的操作。然而,由于字符串的不可变性,频繁的拼接操作可能会导致性能问题。本文将探讨Java中实现高效字符串拼接的技术,包括使用StringBuilder类、StringBuffer类以及Java 8中的StringJoiner类。通过对比这些技术的优缺点,我们将为您提供在不同场景下选择合适的字符串拼接方法的建议。

热门文章

最新文章

推荐镜像

更多