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管理。非常的简单和方便。

相关文章
|
2月前
|
人工智能 监控 Java
Java与AI智能体:构建自主决策与工具调用的智能系统
随着AI智能体技术的快速发展,构建能够自主理解任务、制定计划并执行复杂操作的智能系统已成为新的技术前沿。本文深入探讨如何在Java生态中构建具备工具调用、记忆管理和自主决策能力的AI智能体系统。我们将完整展示从智能体架构设计、工具生态系统、记忆机制到多智能体协作的全流程,为Java开发者提供构建下一代自主智能系统的完整技术方案。
457 4
|
3月前
|
人工智能 Java API
Java AI智能体实战:使用LangChain4j构建能使用工具的AI助手
随着AI技术的发展,AI智能体(Agent)能够通过使用工具来执行复杂任务,从而大幅扩展其能力边界。本文介绍如何在Java中使用LangChain4j框架构建一个能够使用外部工具的AI智能体。我们将通过一个具体示例——一个能获取天气信息和执行数学计算的AI助手,详细讲解如何定义工具、创建智能体并处理执行流程。本文包含完整的代码示例和架构说明,帮助Java开发者快速上手AI智能体的开发。
1221 8
|
3月前
|
人工智能 缓存 监控
使用LangChain4j构建Java AI智能体:让大模型学会使用工具
AI智能体是大模型技术的重要演进方向,它使模型能够主动使用工具、与环境交互,以完成复杂任务。本文详细介绍如何在Java应用中,借助LangChain4j框架构建一个具备工具使用能力的AI智能体。我们将创建一个能够进行数学计算和实时信息查询的智能体,涵盖工具定义、智能体组装、记忆管理以及Spring Boot集成等关键步骤,并展示如何通过简单的对话界面与智能体交互。
1090 1
|
3月前
|
消息中间件 监控 Java
Apache Kafka 分布式流处理平台技术详解与实践指南
本文档全面介绍 Apache Kafka 分布式流处理平台的核心概念、架构设计和实践应用。作为高吞吐量、低延迟的分布式消息系统,Kafka 已成为现代数据管道和流处理应用的事实标准。本文将深入探讨其生产者-消费者模型、主题分区机制、副本复制、流处理API等核心机制,帮助开发者构建可靠、可扩展的实时数据流处理系统。
405 4
|
3月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
416 1
|
3月前
|
安全 Cloud Native Java
Java 模块化系统(JPMS)技术详解与实践指南
本文档全面介绍 Java 平台模块系统(JPMS)的核心概念、架构设计和实践应用。作为 Java 9 引入的最重要特性之一,JPMS 为 Java 应用程序提供了强大的模块化支持,解决了长期存在的 JAR 地狱问题,并改善了应用的安全性和可维护性。本文将深入探讨模块声明、模块路径、访问控制、服务绑定等核心机制,帮助开发者构建更加健壮和可维护的 Java 应用。
297 0
|
3月前
|
监控 Cloud Native Java
Quarkus 云原生Java框架技术详解与实践指南
本文档全面介绍 Quarkus 框架的核心概念、架构特性和实践应用。作为新一代的云原生 Java 框架,Quarkus 旨在为 OpenJDK HotSpot 和 GraalVM 量身定制,显著提升 Java 在容器化环境中的运行效率。本文将深入探讨其响应式编程模型、原生编译能力、扩展机制以及与微服务架构的深度集成,帮助开发者构建高效、轻量的云原生应用。
421 44
|
4月前
|
Java 测试技术 API
2025 年 Java 开发者必知的最新技术实操指南全览
本指南涵盖Java 21+核心实操,详解虚拟线程、Spring Boot 3.3+GraalVM、Jakarta EE 10+MicroProfile 6微服务开发,并提供现代Java开发最佳实践,助力开发者高效构建高性能应用。
767 4
|
4月前
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
165 4
|
4月前
|
消息中间件 OLAP Kafka
Apache Doris 实时更新技术揭秘:为何在 OLAP 领域表现卓越?
Apache Doris 为何在 OLAP 领域表现卓越?凭借其主键模型、数据延迟、查询性能、并发处理、易用性等多方面特性的表现,在分析领域展现了独特的实时更新能力。
460 9

推荐镜像

更多