commons-pool 更新されてた。

Apachecommons-pool 久々に目に留めたのですが、
2018-6-14 に、Maven セントラルリポジトリに、UPされてた。
MariaDB で発生していたバグ、
[POOL-336] GenericObjectPool's borrowObject lock if create() fails with Error - ASF JIRA
など、対応されてた。

久々に目に留まったので、ちょっとラムダで書く、一般的に使えそうなコードを書いてみました。

import java.util.function.Consumer;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
/**
 * GenericPoolProcess
 */
public final class GenericPoolProcess<T>{
   private static GenericPoolProcess inst;

   private GenericObjectPool<T> pool;
   private GenericObjectPoolConfig<T> config;

   private GenericPoolProcess(int maxIdle, int maxTotal, BasePooledObjectFactory<T> factory){
      config = new GenericObjectPoolConfig<T>();
      config.setMaxIdle(maxIdle);
      config.setMaxTotal(maxTotal);
      pool = new GenericObjectPool<>(factory, config);
      try{
         for(int i=0; i < maxIdle; i++){
            pool.addObject();
         }
      }catch(Exception ex){
         throw new RuntimeException(ex);
      }
   }
   @SuppressWarnings("unchecked")
   public static synchronized <T> GenericPoolProcess<T> init(int maxIdle, int maxTotal, BasePooledObjectFactory<T> factory){
      if (maxIdle < 0) throw new IllegalArgumentException("maxIdle mulst be grater than 0");
      if (maxTotal < 2) throw new IllegalArgumentException("maxTotal mulst be grater than 1");
      if (inst==null) inst = new GenericPoolProcess<>(maxIdle, maxTotal, factory);
      return inst;
   }
   /* get は、シングルトンメソッドではない単に参照、initを実行しないとエラー */
   @SuppressWarnings("unchecked")
   public static <T> GenericPoolProcess<T> get(){
      if (inst==null) throw new RuntimeException("Not initt");
      return inst;
   }
   public synchronized void close(){
      if (inst != null) inst.pool.close();
   }

   @SuppressWarnings("unchecked")
   public void exec(Consumer<T> consumer, Consumer<Exception> x){
      try{
         T obj = (T)inst.pool.borrowObject();
         consumer.accept(obj);
         inst.pool.returnObject(obj);
      }catch(Exception ex){
         x.accept(ex);
      }
   }
   @SuppressWarnings("unchecked")
   public static <T> GenericObjectPool<T> getPool(){
      if (inst==null) throw new RuntimeException("No created pool");
      return inst.pool;
   }
}

使用は、、

// IdMaker という Object のプール準備
// IdMakerFactory は、BasePooledObjectFactoryを継承して用意する
GenericPoolProcess<IdMaker> p = GenericPoolProcess.init(1, 3, new IdMakerFactory());

// プールから取り出し実行
p.exec(t->{
   // t is IdMaker
   String id = t.getId();
   
}, x->x.printStackTrace());

p.close();

なんか、こうじゃなくて、Google guice AOP で書ける気がしてきました。
そうすれば、アノテーションメソッドで Pool Object を取得することを
約束したメソッドを自由に書かせることができるでしょう。