Ответ 1
Вы на правильном пути. При создании GenericObjectPool вы можете использовать конструктор, который принимает объект GenericObjectPoolConfig, который содержит все значения конфигурации для пула объектов. Пример ниже позволит вашему пулу расти до 20 соединений до того, как он будет исчерпан...
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMinIdle(2);
config.setMaxIdle(5);
config.setMaxTotal(20);
GenericObjectPool<Cipher> pool;
CipherFactory factory = new CipherFactory();
this.pool = new GenericObjectPool<Cipher>(factory, config);
GenericeObjectPoolConfig также имеет метод setBlockWhenExhausted, чтобы указать поведение, когда пул достиг соединений maxTotal. Подробнее см. https://commons.apache.org/proper/commons-pool/apidocs/org/apache/commons/pool2/impl/BaseObjectPoolConfig.html#setBlockWhenExhausted-boolean-.
Образец, который я реализую при использовании пула общин, состоит в том, чтобы создать 2 интерфейса, один для вашего объединенного объекта и один для вашего factory...
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<PooledCipher>
implements CipherFactory {
private final GenericObjectPoolConfig config;
private final GenericObjectPool<PooledCipher> 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<PooledCipher>(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<PooledCipher> 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<PooledCipher> wrap(PooledCipher cipher) {
return new DefaultPooledObject<PooledCipher>(cipher);
}
}
Реализация PooledCipher...
public class PooledCipherImpl implements PooledCipher {
private final ObjectPool<PooledCipher> pool;
private final Cipher cipher;
private final String secretKeySpecAlgorithm;
private boolean destroyOnClose = false;
public PooledCipherImpl(ObjectPool<PooledCipher> 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.