![JAR search and dependency download from the Maven repository](/logo.png)
org.picocontainer.gems.behaviors.Pooled Maven / Gradle / Ivy
/*****************************************************************************
* Copyright (C) NanoContainer Organization. All rights reserved. *
* ------------------------------------------------------------------------- *
* The software in this package is published under the terms of the BSD *
* style license a copy of which has been included with this distribution in *
* the LICENSE.txt file. *
* *
* Original code by Aslak Hellesoy & Joerg Schaible *
*****************************************************************************/
package org.picocontainer.gems.behaviors;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.lang.reflect.Type;
import org.picocontainer.ComponentAdapter;
import org.picocontainer.PicoContainer;
import org.picocontainer.behaviors.AbstractBehavior;
import org.picocontainer.LifecycleStrategy;
import org.picocontainer.PicoCompositionException;
import com.thoughtworks.proxy.ProxyFactory;
import com.thoughtworks.proxy.factory.StandardProxyFactory;
import com.thoughtworks.proxy.kit.NoOperationResetter;
import com.thoughtworks.proxy.kit.Resetter;
import com.thoughtworks.proxy.toys.nullobject.Null;
import com.thoughtworks.proxy.toys.pool.Pool;
/**
* {@link ComponentAdapter} implementation that pools components.
*
* The implementation utilizes a delegated ComponentAdapter to create the instances of the pool. The
* pool can be configured to grow unlimited or to a maximum size. If a component is requested from
* this adapter, the implementation returns an available instance from the pool or will create a
* new one, if the maximum pool size is not reached yet. If none is available, the implementation
* can wait a defined time for a returned object before it throws a {@link PoolException}.
*
*
* This implementation uses the {@link Pool} toy from the ProxyToys project. This ensures, that any component,
* that is out of scope will be automatically returned to the pool by the garbage collector.
* Additionally will every component instance also implement
* {@link com.thoughtworks.proxy.toys.pool.Poolable}, that can be used to return the instance
* manually. After returning an instance it should not be used in client code anymore.
*
*
* Before a returning object is added to the available instances of the pool again, it should be
* reinitialized to a normalized state. By providing a proper Resetter implementation this can be
* done automatically. If the object cannot be reused anymore it can also be dropped and the pool
* may request a new instance.
*
*
* The pool supports components with a lifecycle. If the delegated {@link ComponentAdapter}
* implements a {@link LifecycleStrategy}, any component retrieved form the pool will be started
* before and stopped again, when it returns back into the pool. Also if a component cannot be
* resetted it will automatically be disposed. If the container of the pool is disposed, that any
* returning object is also disposed and will not return to the pool anymore. Note, that current
* implementation cannot dispose pooled objects.
*
*
* @author Jörg Schaible
* @author Aslak Hellesøy
*/
@SuppressWarnings("serial")
public final class Pooled extends AbstractBehavior {
/**
* Context of the Pooled used to initialize it.
*
* @author Jörg Schaible
*/
public static interface Context {
/**
* Retrieve the maximum size of the pool. An implementation may return the maximum value or
* {@link Pooled#UNLIMITED_SIZE} for unlimited growth.
*
* @return the maximum pool size
*/
int getMaxSize();
/**
* Retrieve the maximum number of milliseconds to wait for a returned element. An
* implementation may return alternatively {@link Pooled#BLOCK_ON_WAIT} or
* {@link Pooled#FAIL_ON_WAIT}.
*
* @return the maximum number of milliseconds to wait
*/
int getMaxWaitInMilliseconds();
/**
* Allow the implementation to invoke the garbace collector manually if the pool is
* exhausted.
*
* @return true
for an internal call to {@link System#gc()}
*/
boolean autostartGC();
/**
* Retrieve the ProxyFactory to use to create the pooling proxies.
*
* @return the {@link ProxyFactory}
*/
ProxyFactory getProxyFactory();
/**
* Retrieve the {@link Resetter} of the objects returning to the pool.
*
* @return the Resetter instance
*/
Resetter getResetter();
/**
* Retrieve the serialization mode of the pool. Following values are possible:
*
* - {@link Pool#SERIALIZATION_STANDARD}
* - {@link Pool#SERIALIZATION_NONE}
* - {@link Pool#SERIALIZATION_FORCE}
*
*
* @return the serialization mode
*/
int getSerializationMode();
}
/**
* The default context for a Pooled.
*
* @author Jörg Schaible
*/
public static class DefaultContext implements Context {
/**
* {@inheritDoc} Returns {@link Pooled#DEFAULT_MAX_SIZE}.
*/
public int getMaxSize() {
return DEFAULT_MAX_SIZE;
}
/**
* {@inheritDoc} Returns {@link Pooled#FAIL_ON_WAIT}.
*/
public int getMaxWaitInMilliseconds() {
return FAIL_ON_WAIT;
}
/**
* {@inheritDoc} Returns false
.
*/
public boolean autostartGC() {
return false;
}
/**
* {@inheritDoc} Returns a {@link StandardProxyFactory}.
*/
public ProxyFactory getProxyFactory() {
return new StandardProxyFactory();
}
/**
* {@inheritDoc} Returns the {@link Pooled#DEFAULT_RESETTER}.
*/
public Resetter getResetter() {
return DEFAULT_RESETTER;
}
/**
* {@inheritDoc} Returns {@link Pool#SERIALIZATION_STANDARD}.
*/
public int getSerializationMode() {
return Pool.SERIALIZATION_STANDARD;
}
}
/**
* UNLIMITED_SIZE
is the value to set the maximum size of the pool to unlimited ({@link Integer#MAX_VALUE}
* in fact).
*/
public static final int UNLIMITED_SIZE = Integer.MAX_VALUE;
/**
* DEFAULT_MAX_SIZE
is the default size of the pool.
*/
public static final int DEFAULT_MAX_SIZE = 8;
/**
* BLOCK_ON_WAIT
forces the pool to wait until an object of the pool is returning
* in case none is immediately available.
*/
public static final int BLOCK_ON_WAIT = 0;
/**
* FAIL_ON_WAIT
forces the pool to fail none is immediately available.
*/
public static final int FAIL_ON_WAIT = -1;
/**
* DEFAULT_RESETTER
is a {@link NoOperationResetter} that is used by default.
*/
public static final Resetter DEFAULT_RESETTER = new NoOperationResetter();
private int maxPoolSize;
private int waitMilliSeconds;
private Pool pool;
private int serializationMode;
private boolean autostartGC;
private boolean started;
private boolean disposed;
private boolean delegateHasLifecylce;
private transient List