`

commons-pool连接池的实现应用

 
阅读更多

一、描述: 

apache commons-pool本质上是"对象池",即通过一定的规则来维护对象集合的容器;commons-pool用来实现"连接池"或"任务池"等,dbcp也是基于commons-pool实现。

二、commons-pool实现思路:

将"对象集合"池化,任何通过pool进行对象存取的操作,都会严格按照"pool配置"试试的创建对象、阻塞控制、销毁对象等。实现了对象集合的管理以及对象的分发。

a.将创建对象的方式,使用工厂模式;

b.通过"pool配置"来约束对象存取的时机

c.将对象列表保存在队列中(LinkedList)

三、实例演示(FTP连接池管理):吐舌头

public abstract class AbstractObjectPool<T>{

   private final GenericObjectPool<T> internalPool;

   public AbstractObjectPool(GenericObjectPool.Config poolConfig,                             PoolableObjectFactory factory){
        this.internalPool=new GenericObjectPool(factory,poolConfig);
  }

   public T getResource(){
      return this.internalPool.borrowObject();
   }
   
   public void returnResource(T  resource){
       this.internalPool.returnObject(resource);
  }
   
   public void destroy(){
       this.internalPool.close();
   }

}

 FTPPool.java继承了抽象类AbstractObjectPool.java,在构造方法中实例化FTPPoolableObjectFactory,处理GenericObjectPool中的操作。

public class FTPPool extends<AbstractObjectPool>{

   public FTPPool(GenericObjectPool.Config poolConfig,String host,int port,String user,String password,String passiveModeConf){
         
     super(poolConfig,new FTPPoolableObjectFactort(host, port, user, password, passiveModeConf));
   }

}

 FTPPoolableObjectFactort.java继承BasePoolableObjectFactory,其中的方法分别为:

GenericObjectPool内部会回调makeObject创建对象

GenericObjectPool内部会回调destroyObject销毁对象

GenericObjectPool内部会回调validateObject检验对象

public class FTPPoolableObjectFactory extends BasePoolableObjectFactory<FTPClient>{
   private String host;  
   private int port;  
   private String user;  
   private String password;  
   private String passiveModeConf;

   public FTPPoolableObjectFactory (String host,int port,String    user,String password,String passiveModeConf){
    this.host=host;
    this.port = port;
    this.user = user;
    this.password = password;
    this.passiveModeConf = passiveModeConf; 
  }

   @Override
    public FTPClient makeObject() throws Exception {
        FTPClient ftpClient = getFTPClient();
        return ftpClient;
    }
   
   @Override
    public void destroyObject(FTPClient client) throws Exception {
        if (client != null) {
            disconnect(client);
        }
    }

    @Override
    public boolean validateObject(FTPClient obj) {
        if (obj != null) {
            FTPClient ftpClient = obj;
            try {
                return ftpClient.isConnected();
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
                return false;
            }
        }
        return false;
    }
    
   private void setFileType(FTPClient ftpClient) throws FTPClientException {
        try {
            if (binaryTransfer) {
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            } else {
                ftpClient.setFileType(FTPClient.ASCII_FILE_TYPE);
            }
        } catch (IOException e) {
            throw new FTPClientException("Could not to set file type.", e);
        }
        msg = " setFileType(FTPClient " + ftpClient + ") 结束";
        LOGGER.error(msg);
    }

    private FTPClient getFTPClient() throws FTPClientException {
        FTPClient ftpClient = new FTPClient(); // 构造一个FtpClient实例
        ftpClient.setControlEncoding(encoding); // 设置字符集        
        connect(ftpClient); // 连接到ftp服务器
        // 设置为passive模式
        if (passiveMode) {
            ftpClient.enterLocalPassiveMode();
        }
        setFileType(ftpClient); // 设置文件传输类型
        try {
            ftpClient.setSoTimeout(CLIENT_TIMEOUT);
        } catch (SocketException e) {
            throw new FTPClientException("Set timeout error.", e);
        }
        return ftpClient;
    }
    
 private boolean connect(FTPClient ftpClient) throws FTPClientException {
        try {
            ftpClient.connect(host, port);           
            // 连接后检测返回码来校验连接是否成功
            int reply = ftpClient.getReplyCode();
            
            if (FTPReply.isPositiveCompletion(reply)) {
                // 登陆到ftp服务器
                msg = "login(" + username + ", " + password + ")";
                if (ftpClient.login(username, password)) {
                    setFileType(ftpClient);
                    return true;
                }
            } else {
                ftpClient.disconnect();
                throw new FTPClientException("FTP server refused connection.");
            }
        } catch (IOException e) {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect(); // 断开连接
                } catch (IOException e1) {
                    throw new FTPClientException("Could not disconnect from server.", e);
                }
                
            }
            throw new FTPClientException("Could not connect to server.", e);
        }
        return false;
    }
   
    private void disconnect(FTPClient ftpClient) throws FTPClientException {
        try {
            ftpClient.logout();
            if (ftpClient.isConnected()) {
                ftpClient.disconnect();
            }
        } catch (IOException e) {
            throw new FTPClientException("Could not disconnect from server.", e);
        }
    }
}

 客户端测试方法:

public static void main(String[] args) throws Exception{
   //设置连接池的配置参数
  GenericObjectPool.Config config = new Config();
   //最大池容量  
   config.maxActive=5;

   //从池中取对象达到最大时,继续创建新对象. 
   config.whenExhaustedAction =    GenericObjectPool.WHEN_EXHAUSTED_GROW;

   //池为空时取对象等待的最大毫秒数
   config.maxWait=60*1000; 

   //取出对象时验证(此处设置成验证ftp是否处于连接状态)
   config.testOnBorrow=true; 

    //还回对象时验证(此处设置成验证ftp是否处于连接状态)
   config.testOnReturn=true;

   FTPPool pool = new FTPPool(config,"XXXXXX",21,"xxxxxx","xxxxxx","true");
  
  System.out.println("borrowSize1:"+pool.borrowSize());
  System.out.println("inPoolSize1:"+pool.inPoolSize());
  long begin=System.currentTimeMillis();

  for(int i=0;i<8;i++){
     FTPClient ftpClient = pool.getResource();
     System.out.println("ftpClient"+(i+1)+" isConnected:"+ftpClient.isConnected());

     pool.returnResource(ftpClient);
  }
  
  System.out.println("time:"+(System.currentTimeMillis()-begin)); 
  System.out.println("borrowSize2:"+pool.borrowSize());
  System.out.println("inPoolSize2:"+pool.inPoolSize());
  pool.destroy();
}

 

 

 

分享到:
评论

相关推荐

    java连接池有关jar:commons-pool-1.2.jar+commons-pool-1.3.jar+commons-pool.jar

    java连接池;java连接池jar;commons-pool-1.2.jar;commons-pool-1.3.jar+commons-pool.jar;java连接池jar包java连接池;java连接池jar;commons-pool-1.2.jar;commons-pool-1.3.jar+commons-pool.jar;java连接池jar包...

    commons-pool2-2.11.1-bin.zip

    DBCP(DataBase Connection Pool)是 apache common上的一个 java 连接池项目,也是 tomcat 使用的连接池组件,依赖 于Jakarta commons-pool 对象池机制,DBCP可以直接的在应用程序中使用。 使用DBCP会用到commons-...

    commons-pool-1.3.jar 和commons-dbcp-1.2.2.jar

    总的来说,"commons-pool-1.3.jar"和"commons-dbcp-1.2.2.jar"是Java开发中处理数据库连接池的关键组件,它们能够帮助开发者更有效地管理和复用数据库连接,提高应用的运行效率。同时,这两个库还可以解决特定情况下...

    SpringBoot2.2+commons-pool2实现多Ftp连接池完整项目,开箱即用,经过长期生产使用稳定可靠

    使用JDK1.8、SpringBoot2.2.10.RELEASE、lombok1.18.8、guava23.0、hutool5.3.10、commons-pool2 2.7.0、tika1.22等实现多Ftp连接池实现,通过守护线程实现连接池内连接可用性校验,配置最大、最小连接个数防止Ftp...

    commons-dbcp-1.4.jar和commons-pool-1.5.6.jar

    Apache Commons DBCP是Apache Commons项目的一部分,它提供了一个基于Apache Commons Pool的数据库连接池实现。数据库连接池是一种管理数据库连接的技术,通过复用已建立的数据库连接,减少创建和销毁连接的开销,...

    commons-dbcp-1.2.1.jar + commons-pool-1.4.jar + commons-collections-3.2.jar

    在Java开发中,数据库连接管理是一项关键任务,而Apache Commons DBCP(Database Connection Pool)是广泛使用的数据库连接池实现之一。本主题将详细解析标题和描述中提及的三个核心库:`commons-dbcp-1.2.1.jar`、`...

    commons-pool 等jar包

    DBCP则是基于commons-pool的数据库连接池实现。它提供了数据库连接的创建、管理和分配服务。在DBCP中,数据库连接被视为可池化的对象,当应用程序需要连接时,可以从池中获取;当操作完成,连接将被返回到池中,而...

    commo-pool, commons-pool commons-pool commons-pool

    总的来说,Apache Commons Pool是一个强大的工具,它简化了对象池的实现,使得开发者能够更高效地管理资源,提高应用程序的性能和稳定性。了解和熟练使用这个库对于任何Java开发者,尤其是涉及数据库连接管理或者...

    commons-pool-1.5.6.jar

    连接池commons-pool-1.5.6的jar包

    commons-pool2-2.6.0 jar包

    Commons Pool2和Commons DBCP2是两个在Java开发中常用的开源库,它们主要用于对象池管理,特别是数据库连接池的实现。这两个库都属于Apache Commons项目,为开发者提供了高效、可靠的资源管理工具。 首先,我们来...

    commons-pool-1.3.jar+commons-collections-3.2.1.jar

    例如,Struts使用`commons-collections`进行请求参数的处理和验证,Spring利用`commons-pool`实现数据库连接池,而Hibernate可能依赖两者来优化数据访问和资源管理。了解并熟练使用这些库,能帮助开发者提高程序效率...

    commons-pool2-2.4.2.jar

    Apache Commons Pool2是一个Java对象池库,用于管理资源对象,如数据库连接或网络套接字。这个库的主要目的是提高性能和资源效率,通过重用已创建的对象而不是每次需要时都创建新的。在给定的场景中,`commons-pool2...

    dbcp连接池所需jar(commons-collections-3.1.jar,commons-dbcp-1.2.jar,commons-pool-1.6.)

    DBCP(Database Connection Pool)是Apache组织提供的一个开源数据库连接池组件,它的全称为"Jakarta Commons DBCP"。这个连接池库被设计用来管理数据库连接,提高应用程序的性能和效率。在Java应用程序中,频繁地...

    最新连接redis数据库连接池commons-pool-2.5.0

    需要使用Redis连接池的话,还需commons-pool包,提供了强大的功能,包含最新的jar包

    commons-collections.jar、commons-pool.jar、commons-dbcp-1.2.1.jar

    Apache Commons Pool提供了多种对象池实现,适用于数据库连接池、线程池等多种场景。在高并发应用中,对象池可以显著减少系统资源的消耗,提升系统性能。 最后,`commons-dbcp-1.2.1.jar`是Apache Commons DBCP ...

    commons-collections-3.1.jar;commons-dbcp-1.2.1.jar;commons-pool-1.2.jar

    描述中提到的“tomcat 连接池”是指Tomcat服务器中的JDBC连接池实现,通常使用的就是Apache Commons DBCP。在Tomcat配置中,可以通过设置`context.xml`或`server.xml`来启用和配置DBCP,以优化对数据库的访问。 ...

    commons-pool-1.6.jar.zip

    Apache Commons Pool 是一个Java对象池库,主要用于提供各种对象池实现,以便在多个请求之间复用对象,从而提高性能和减少资源消耗。标题中的"commons-pool-1.6.jar.zip"表明这是一个包含Apache Commons Pool 1.6...

    commons-pool2-2.8.1.jar

    《Apache Commons Pool 2.8.1:高效对象池实现详解》 Apache Commons Pool 是一个广泛使用的开源组件,主要用于提供对象池化的实现。在Java世界里,对象池化是一种优化资源管理的重要技术,通过复用已创建的对象,...

    jdbc用到的jar包(commons-collections-3.1.jar、commons-dbcp-1.2.2.jar、commons-pool.jar)

    这是另一个Apache Commons项目,它是通用对象池实现,DBCP中的连接池就依赖于它。Commons Pool提供了一种高效的、基于对象池的机制,用于管理可重用对象。在DBCP中,它负责管理数据库连接的创建、分配和回收,确保...

    commons-pool2-2.6.0-bin.zip

    这个库特别适用于Apache DBCP(数据库连接池)这样的项目,DBCP依赖于Commons Pool来管理数据库连接的生命周期,确保高效地复用这些连接,从而提高应用程序的性能和资源利用率。 在`commons-pool2-2.6.0`这个压缩包...

Global site tag (gtag.js) - Google Analytics