Java 在GenericObject池中创建对象
我正在研究Java 在GenericObject池中创建对象,java,object,generics,apache-commons,pool,Java,Object,Generics,Apache Commons,Pool,我正在研究GenericObjectPool,方法是将Cipher放入池中,以便可以重用 GenericObjectPool<Cipher> pool; CipherFactory factory = new CipherFactory(); this.pool = new GenericObjectPool<Cipher>(factory); pool.setMaxTotal(10); pool.setBlockWhenExhausted(true); pool.s
GenericObjectPool
,方法是将Cipher
放入池中,以便可以重用
GenericObjectPool<Cipher> pool;
CipherFactory factory = new CipherFactory();
this.pool = new GenericObjectPool<Cipher>(factory);
pool.setMaxTotal(10);
pool.setBlockWhenExhausted(true);
pool.setMaxWaitMillis(30 * 1000);
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<Cipher> pool;
CipherFactory factory = new CipherFactory();
this.pool = new GenericObjectPool<Cipher>(factory, config);
密码工厂实现
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);
}
}
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);
}
}
}
像这样使用它
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。池最多有10个,因此如果您不将它们返回到池中,那么会出现错误吗?如果你想创建更多的池,如果池用完了,那么看起来你根本不需要池,你可以在需要更多的时候继续创建它们。我走对了吗?如果你想继续使用池,就不需要了。一个池应该有有限数量的资源,就像在本例中,您将其设置为10。这意味着你不能超过10,如果他们都很忙,你需要等待一个在请求之前可用。另一方面,如果你不想等待,这意味着你没有限制,因此不需要池。@tima我看到了,如果池大小为空,它可以增加池大小。但我不确定在我的情况下是否可以这样做。你可以试试,我认为这是apache commons pool(~2012)的一个旧版本。您还可以尝试设置
pool.setMaxTotal(-1)像这样的代码>应该允许您需要的尽可能多的对象。它并没有真正增加它。这是如何让池增长的?它只是增加了初始大小。我注意到,有一些示例使用了GenericObjectPoolConfig
。既然我可以使用pool.setMaxTotal(20),为什么需要它呢
而不是config.setMaxTotal(20)代码>。实际上有什么区别?让我先试试我使用GenericObjectPoolConfig,因为我通常创建该对象并根据配置文件设置值。在我的例子中,我使用的是spring,因此我可以创建一个GenericObjectPoolConfigBean并初始化属性文件中的所有属性。嗨,Tony,我编辑了我的答案,以使其更接近可编译的解决方案,并演示如何销毁对象。希望这更清楚。
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);
}
}
}
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);
}
}