首页 > 其他分享 >【键值-对象池】GenericKeyedObjectPool

【键值-对象池】GenericKeyedObjectPool

时间:2023-05-11 16:58:42浏览次数:41  
标签:String 对象 private 键值 key public GenericKeyedObjectPool

目录

GenericKeyedObjectPool

​ 通用池化框架commons-pool2实践,其中提到了可以池化一个对象和一组对象,一个对象用到了GenericObjectPool这个类,一组对象用到了GenericKeyedObjectPool这个类。顾名思义,键值对象池。就是通过一个key对应一个对象类型来组合对象池,其本质上就是一个Mapkey是自定义,value就是org.apache.commons.pool2.ObjectPool,而但对象池化类GenericObjectPool也是实现了这个接口。

注意:

  1. Map的用的ConcurrentHashMap,是线程安全的。
  2. 获取和回收太频繁,会遇到性能问题。

1. 依赖

<dependency>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-pool2</artifactId>
     <version>2.7.0</version>
</dependency>

2. 配置

例如:配置多sftp主机连接

sftp:
  hosts:
    remote-1:
      host: 127.0.0.1
      port: 22
      username: root
      password: 1234
    remote-2:
      host: 127.0.0.2
      port: 22
      username: root
      password: 1234

3. 连接对象类

  • 被对象池管理的对象
  • 可以想象为一个连接,创建复杂,比如数据库或者redis或者socket之类的对象
@Data
@ConfigurationProperties("sftp")
public class SftpProperties {
    private String host = "localhost";
    private int port = 22;
    private String username;
    private String password = "";
    private LinkedHashMap<String, SftpProperties> hosts;
  	...
}

4. 对象池工厂

然后就是池化工厂类,这个类需要定义keyvalue的类型,然后就是照葫芦画瓢。继承BaseKeyedPooledObjectFactory<K, V>类,并重写create()、wrap()等方法

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

/**
 * 对象池工厂
 */
private static class KeyedPooledClientFactory extends BaseKeyedPooledObjectFactory<String, SftpClient> {

    private final Map<String, SftpProperties> SftpPropertiesMap;

    private KeyedPooledClientFactory(Map<String, SftpProperties> SftpPropertiesMap) {
      this.SftpPropertiesMap = SftpPropertiesMap;
    }

    /**
 	* 根据当前key(remote-1、remote-2)得到的配置信息,创建sftp客户端
 	*/
    public SftpClient create(String key) {
      //SftpClient构造中,根据key拿到对应的主机配置后初始化sftp连接对象
      return new SftpClient(SftpPropertiesMap.get(key));
    }

  	/**
     * common-pool2 中创建了 DefaultPooledObject 对象对对象池中对象进行的包装。
     * 将我们自定义的对象放置到这个包装中,工具会统计对象的状态、创建时间、更新时间、返回时间、出借时间、使用时间等等信息进行统计
     */
    public PooledObject<SftpClient> wrap(SftpClient sftpClient) {
      return new DefaultPooledObject<>(sftpClient);
    }

    /**
     * 校验对象是否可用
     */
    public boolean validateObject(String key, PooledObject<SftpClient> p) {
      return p.getObject().test();
    }

    /**
     * 销毁对象
     */
    public void destroyObject(String key, PooledObject<SftpClient> p) {
      p.getObject().disconnect();
    }
  }

com.funtester.funpool.KeyPoolFactory#destroyObject方法并不是必需的,如果池化的对象除了内存以外不需要额外的资源释放,就不用重写这个方法了。还有一种情况就是对象信息需要清除,比如org.apache.http.client.methods.HttpGet,需要把请求地址和请求头等信息清除,这个需要跟业务需求保持一致。不一定是全都清除。

5. 使用

public class SftpPool {
  
  //池化一组对象用GenericKeyedObjectPool类
  private GenericKeyedObjectPool<String, SftpClient> internalKeyedPool;

  public SftpPool(Map<String, SftpProperties> SftpPropertiesMap, PoolProperties poolProperties) {
    this.internalKeyedPool = new GenericKeyedObjectPool<>(SftpPropertiesMap, getKeyedPoolConfig(poolProperties));
  }

 /**
  * 根据key,在池中借对象
  */
  public SftpClient borrowObject(String key) {
    try {
      internalKeyedPool.borrowObject(key);
    } catch (Exception e) {
      throw new PoolException("COULD_NOT_GET_A_RESOURCE_FROM_THE_POOL");
    }
  }

 /**
  * 根据key,往池中归还对象
  */
  public void returnObject(String key, SftpClient sftpClient) {
    try {
        internalKeyedPool.returnObject(key, sftpClient);
    } catch (Exception e) {
      throw new PoolException("COULD_NOT_GET_A_RESOURCE_FROM_THE_POOL");
    }
    
    ...
  }

标签:String,对象,private,键值,key,public,GenericKeyedObjectPool
From: https://www.cnblogs.com/lihw/p/17391562.html

相关文章

  • APIView执行流程(源码分析)、Request对象源码分析
    目录一、APIView执行流程——源码分析(难,了解)1.1基于APIView+JsonResponse编写接口1.2基于APIView+Response写接口1.3APIView的执行流程二、Request对象源码分析(难,了解)一、APIView执行流程——源码分析(难,了解)1.1基于APIView+JsonResponse编写接口#原来基于django原生的Vi......
  • Oracle 对象批量进行授权
    环境:oracle给用户多表只读权限select'grantselecton'||owner||'.'||object_name||''to用户名;'fromdba_objectswhereownerin(‘owner’)andobject_type='TABLE';批量创建多个同义词SELECT'createorreplaceSYNONYM用户......
  • K8S API资源对象NetworkPolicy
    NetworkPolicy用来控制Pod与Pod之间的网络通信,它也支持针对Namespace进行限制。基于白名单模式,符合规则的对象通过,不符合的拒绝。应用场景举例:PodA不能访问PodB;开发环境所有Pod不能访问测试命名空间;提供对外访问时,限制外部IP;官方NetworkPolicyYAML示例:apiVersion:netwo......
  • JavaScript 面向对象编程
    面向对象编程ObjectOrientedProgramming面向对象编程用对象把数据和方法聚合起来。面向对象编程的优点能写出模块化的代码能使得代码更灵活能提高代码的可重用性面向对象编程的原则继承(inheritance):子类/派生类从父类/基类/超类中派生,形成继承结构封装(encapsulati......
  • python基础学习-面向对象
     Python-Core-50-Courses/第17课:面向对象编程入门.mdatmaster·jackfrued/Python-Core-50-Courses(github.com)Python-Core-50-Courses/第18课:面向对象编程进阶.mdatmaster·jackfrued/Python-Core-50-Courses(github.com)......
  • JAVA学习笔记随记3(面向对象高级)
    类变量类变量的内存布局目前对于类变量的内存布局不能一概而论。对于jdk8及其之前的版本,类变量放在方法区的静态域中。对于之后版本的jdk而言,类变量放在堆区。但实例化出的对象,类变量都是通过引用的。无论如何有以下两个公示:1.静态对象被所有对象共享。2.static类变量,在......
  • 第五节:面向对象
    三个特征:封装,继承,多态。开发:找对象,没有对象就创建对象,使用对象,维护对象。类:对现实生活中事物的描述对象:实实在在存在的个体。对象就是在堆内存中用new建立的实体,实体就是用来存储多个数据的,对象有很多个实体,比如年龄,性别,姓名等。凡是用来存储多个数据的我们都叫做实体。定义......
  • C++ 类和对象: 初始化列表
    1.回顾构造函数构造函数是6个默认的成员函数之一,完成对象初始化的工作而在构造函数中,有两种初始化对象的方式,初始化列表和函数体内赋值首先来回顾一下用函数体内赋值方法进行初始化#include<iostream>usingnamespacestd;classDate{public: Date(intyear=1,......
  • C++ 类和对象: const关键字
    1.const关键字在C语言中,const关键字用来修饰变量,表示变量的值不能被修改在C++中,const可以修饰变量,也可以用来修饰对象和类成员变量下面先来看一下,const修饰对象使用const修饰的对象d1,调用成员函数报错,这是为什么?那么只要把this指针类型改为constDate*,......
  • springboot 项目中返回前端对象错误显示是string格式
    原因是返回json对象后面跟了一段,如下图这个错误藏的比较隐蔽,有个小的对象没有实现getter方法。在返回前端对象里,所有对象都得可以序列化和反序列化,对应的对象中所有属性是否都实现getter和setter等序列化。......