在GenericObjectPool中创建对象

我正在通过将Cipher放入池中来研究GenericObjectPool ,以便可以重用它。

 GenericObjectPool pool; CipherFactory factory = new CipherFactory(); this.pool = new GenericObjectPool(factory); pool.setMaxTotal(10); pool.setBlockWhenExhausted(true); pool.setMaxWaitMillis(30 * 1000); 

CipherFactory

 public class CipherFactory extends BasePooledObjectFactory { private boolean running = false; @Override public Cipher create() throws Exception { return Cipher.getInstance("DESede/CBC/NoPadding"); } @Override public PooledObject wrap(Cipher arg0) { return new DefaultPooledObject(arg0); } @Override public boolean validateObject(PooledObject p) { //Ensures that the instance is safe to be returned by the pool return true; } @Override public void destroyObject(PooledObject p) { //Destroys an instance no longer needed by the pool. System.out.println("destroying"); } @Override public void activateObject(PooledObject p) throws Exception { //Reinitialize an instance to be returned by the pool setRunning(true); } @Override public void passivateObject(PooledObject p) throws Exception { // reset the object after the object returns to the pool setRunning(false); } public void setRunning(boolean running) { this.running = running; } // } 

这是我在Example类中实现ObjectPool

 public Key a(byte[] afyte) throws Exception { Cipher cipher = null; cipher = pool.borrowObject(); //get the object from the pool try { System.out.println("****************** After borrow ****************"); printPool(); cipher.init(Cipher.DECRYPT_MODE, mkkey, algParamSpec); byte[] de = cipher.doFinal(afyte); SecretKey mk = new SecretKeySpec(de, "DESede"); return mk; } catch (Exception e) { pool.invalidateObject(cipher); cipher = null; } finally { if (null != cipher) { pool.returnObject(cipher); System.out.println("****************** After return ****************"); printPool(); } } return (Key) cipher; } 

printPool

 public void printPool() { System.out.println("Pool for cipher with instances DESede/CBC/NoPadding"); System.out.println("Active [" + pool.getNumActive() + "]"); //Return the number of instances currently borrowed from this pool System.out.println("Idle [" + pool.getNumIdle() + "]"); //The number of instances currently idle in this pool System.out.println("Total Created [" + pool.getCreatedCount() + "]"); } 

我在正确的道路上吗? 是否可以增加池大小?

编辑

@http的答案对我来说很好。 但如果我有另一种方法encryptECB(Key key, byte[] b) ,我应该怎么写?

任何帮助,将不胜感激 !

你走在正确的轨道上。 构造GenericObjectPool时,可以使用接受GenericObjectPoolConfig对象的构造函数,该对象包含对象池的所有配置值。 下面的示例将让您的池在耗尽之前增长到20个连接…

 GenericObjectPoolConfig config = new GenericObjectPoolConfig(); config.setMinIdle(2); config.setMaxIdle(5); config.setMaxTotal(20); GenericObjectPool pool; CipherFactory factory = new CipherFactory(); this.pool = new GenericObjectPool(factory, config); 

GenericeObjectPoolConfig还有一个setBlockWhenExhausted方法,用于指定池达到maxTotal连接时的行为。 有关详细信息,请参阅https://commons.apache.org/proper/commons-pool/apidocs/org/apache/commons/pool2/impl/BaseObjectPoolConfig.html#setBlockWhenExhausted-boolean- 。

我在使用公共池时实现的模式是创建2个接口,一个用于池化对象,另一个用于工厂……

 public interface PooledCipher extends java.io.Closeable { byte[] doFinal(byte[] bytes) throws Exception; SecretKeySpec getSecretKeySpec(byte[] bytes) throws Exception; } public interface CipherFactory { PooledCipher getCipher() throws Exception; void close(); } 

CipherFactory实现……

 public class CipherFactoryImpl extends BasePooledObjectFactory implements CipherFactory { private final GenericObjectPoolConfig config; private final GenericObjectPool pool; private final String transformation; private final int opmode; private final Key key; private final AlgorithmParameters params; private final String secretKeySpecAlgorithm; public CipherFactoryImpl(GenericObjectPoolConfig config, String transformation, int opmode, Key key, AlgorithmParameters params, String secretKeySpecAlgorithm) { this.config = config; this.pool = new GenericObjectPool(this, config); this.transformation = transformation; this.opmode = opmode; this.key = key; this.params = params; this.secretKeySpecAlgorithm = secretKeySpecAlgorithm } @Override public PooledCipher create() throws Exception { return new PooledCipherImpl(pool, transformation, opmode, key, params, secretKeySpecAlgorithm); } @Override public PooledCipher getCipher() throws Exception { return pool.borrowObject(); } @Override public void destroyObject(PooledObject p) throws Exception { try { PooledCipherImpl cipherImpl = (PooledCipherImpl)p.getObject(); // do whatever you need with cipherImpl to destroy it } finally { super.destroyObject(p); } } @Override public void close() { pool.close(); } @Override public PooledObject wrap(PooledCipher cipher) { return new DefaultPooledObject(cipher); } } 

PooledCipher实现……

 public class PooledCipherImpl implements PooledCipher { private final ObjectPool pool; private final Cipher cipher; private final String secretKeySpecAlgorithm; private boolean destroyOnClose = false; public PooledCipherImpl(ObjectPool pool, String transformation, int opmode, Key key, AlgorithmParameters params, String secretKeySpecAlgorithm) { this.pool = pool; this.cipher = Cipher.getInstance(transformation); this.cipher.init(opmode, key, params); this.secretKeySpecAlgorithm = secretKeySpecAlgorithm; } @Override public byte[] doFinal(byte[] bytes) throws Exception { try { return cipher.doFinal(bytes); } catch (Exception e) { destroyOnClose = true; throw e; } } @Override public SecretKeySpec getSecretKeySpec(byte[] bytes) { return new SecretKeySpec(doFinal(bytes), secretKeySpecAlgorithm); } @Override public void close() throws IOException { try { if (destroyOnClose) { pool.destroyObject(this); } else { pool.returnObject(this); } } catch (Exception e) { throw new IOException(e); } } } 

然后你像这样构建你的CipherFactory ……

 String transformation = "DESede/CBC/NoPadding"; String secretKeySpecAlgorithm = "DESede"; GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); // set up the poolConfig here poolConfig.setMaxTotal(20); CipherFactory cipherFactory = new CipherFactoryImpl(poolConfig, transformation, Cipher.DECRYPT_MODE, mkkey, algParamSpec, secretKeySpecAlgorithm); 

并像这样使用它……

 public Key unwrapKey(byte[] tmkByte) throws Exception { try (PooledCipher cipher = cipherFactory.getCipher()) { return cipher.getSecretKeySpec(tmkByte); } } 

您还可以重用PooledCipher和CipherFactory接口来创建其他实现,例如JCA。