org.picocontainer.defaults
Class DefaultPicoContainer

java.lang.Object
  extended by org.picocontainer.defaults.DefaultPicoContainer
All Implemented Interfaces:
java.io.Serializable, ComponentMonitorStrategy, Disposable, MutablePicoContainer, PicoContainer, Startable

public class DefaultPicoContainer
extends java.lang.Object
implements MutablePicoContainer, ComponentMonitorStrategy, java.io.Serializable

The Standard PicoContainer/MutablePicoContainer implementation. Constructing a container c with a parent p container will cause c to look up components in p if they cannot be found inside c itself.

Using Class objects as keys to the various registerXXX() methods makes a subtle semantic difference:

If there are more than one registered components of the same type and one of them are registered with a Class key of the corresponding type, this component will take precedence over other components during type resolution.

Another place where keys that are classes make a subtle difference is in ImplementationHidingComponentAdapter.

This implementation of MutablePicoContainer also supports ComponentMonitorStrategy.

Version:
$Revision: 1.8 $
Author:
Paul Hammant, Aslak Hellesøy, Jon Tirsén, Thomas Heller, Mauro Talevi
See Also:
Serialized Form

Nested Class Summary
private  class DefaultPicoContainer.OrderedComponentAdapterLifecycleManager
           Implementation of lifecycle manager which delegates to the container's component adapters.
 
Field Summary
private  java.util.Set children
           
private  java.util.Set childrenStarted
           
private  ComponentAdapterFactory componentAdapterFactory
           
private  java.util.List componentAdapters
           
private  java.util.Map componentKeyToAdapterCache
           
private  boolean disposed
           
private  LifecycleManager lifecycleManager
           
private  LifecycleStrategy lifecycleStrategyForInstanceRegistrations
           
private  java.util.List orderedComponentAdapters
           
private  PicoContainer parent
           
private  boolean started
           
 
Constructor Summary
DefaultPicoContainer()
          Creates a new container with a (caching) DefaultComponentAdapterFactory and no parent container.
DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory)
          Creates a new container with a custom ComponentAdapterFactory and no parent container.
DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory, LifecycleStrategy lifecycleStrategyForInstanceRegistrations, PicoContainer parent)
          Creates a new container with a custom ComponentAdapterFactory, LifecycleStrategy for instance registration, and a parent container.
DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent)
          Creates a new container with a custom ComponentAdapterFactory and a parent container.
DefaultPicoContainer(ComponentMonitor monitor)
          Creates a new container with the DefaultComponentAdapterFactory using a custom ComponentMonitor
DefaultPicoContainer(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, PicoContainer parent)
          Creates a new container with the DefaultComponentAdapterFactory using a custom ComponentMonitor and lifecycle strategy
DefaultPicoContainer(ComponentMonitor monitor, PicoContainer parent)
          Creates a new container with the DefaultComponentAdapterFactory using a custom ComponentMonitor
DefaultPicoContainer(LifecycleStrategy lifecycleStrategy, PicoContainer parent)
          Creates a new container with the DefaultComponentAdapterFactory using a custom lifecycle strategy
DefaultPicoContainer(PicoContainer parent)
          Creates a new container with a (caching) DefaultComponentAdapterFactory and a parent container.
 
Method Summary
 void accept(PicoVisitor visitor)
          Accepts a visitor that should visit the child containers, component adapters and component instances.
 boolean addChildContainer(PicoContainer child)
          Add a child container.
private  void addOrderedComponentAdapter(ComponentAdapter componentAdapter)
           
 void changeMonitor(ComponentMonitor monitor)
          Changes monitor in the ComponentAdapterFactory, the component adapters and the child containers, if these support a ComponentMonitorStrategy.
private  boolean childStarted(PicoContainer child)
          Checks the status of the child container to see if it's been started to prevent IllegalStateException upon stop
 ComponentMonitor currentMonitor()
          Returns the first current monitor found in the ComponentAdapterFactory, the component adapters and the child containers, if these support a ComponentMonitorStrategy.
 void dispose()
          Dispose the components of this PicoContainer and all its logical child containers.
 ComponentAdapter getComponentAdapter(java.lang.Object componentKey)
          Find a component adapter associated with the specified key.
 ComponentAdapter getComponentAdapterOfType(java.lang.Class componentType)
          Find a component adapter associated with the specified type.
 java.util.Collection getComponentAdapters()
          Retrieve all the component adapters inside this container.
 java.util.List getComponentAdaptersOfType(java.lang.Class componentType)
          Retrieve all component adapters inside this container that are associated with the specified type.
 java.lang.Object getComponentInstance(java.lang.Object componentKey)
          Retrieve a component instance registered with a specific key.
 java.lang.Object getComponentInstanceOfType(java.lang.Class componentType)
          Find a component instance matching the specified type.
 java.util.List getComponentInstances()
          Retrieve all the registered component instances in the container, (not including those in the parent container).
 java.util.List getComponentInstancesOfType(java.lang.Class componentType)
          Returns a List of components of a certain componentType.
private  java.lang.Object getInstance(ComponentAdapter componentAdapter)
           
 PicoContainer getParent()
          Retrieve the parent container of this container.
 MutablePicoContainer makeChildContainer()
          Make a child container, using the same implementation of MutablePicoContainer as the parent.
 ComponentAdapter registerComponent(ComponentAdapter componentAdapter)
          Register a component via a ComponentAdapter.
 ComponentAdapter registerComponentImplementation(java.lang.Class componentImplementation)
          Register a component using the componentImplementation as key.
 ComponentAdapter registerComponentImplementation(java.lang.Object componentKey, java.lang.Class componentImplementation)
          Register a component.
 ComponentAdapter registerComponentImplementation(java.lang.Object componentKey, java.lang.Class componentImplementation, java.util.List parameters)
          Same as registerComponentImplementation(java.lang.Object, java.lang.Class, org.picocontainer.Parameter[]) but with parameters as a List.
 ComponentAdapter registerComponentImplementation(java.lang.Object componentKey, java.lang.Class componentImplementation, Parameter[] parameters)
          Register a component and creates specific instructions on which constructor to use, along with which components and/or constants to provide as constructor arguments.
 ComponentAdapter registerComponentInstance(java.lang.Object component)
          Register an arbitrary object.
 ComponentAdapter registerComponentInstance(java.lang.Object componentKey, java.lang.Object componentInstance)
          Register an arbitrary object as a component in the container.
 boolean removeChildContainer(PicoContainer child)
          Remove a child container from this container.
 void start()
          Start the components of this PicoContainer and all its logical child containers.
 void stop()
          Stop the components of this PicoContainer and all its logical child containers.
 ComponentAdapter unregisterComponent(java.lang.Object componentKey)
          Unregister a component by key.
 ComponentAdapter unregisterComponentByInstance(java.lang.Object componentInstance)
          Unregister a component by instance.
 void verify()
          Deprecated. since 1.1 - Use "new VerifyingVisitor().traverse(this)"
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

componentKeyToAdapterCache

private java.util.Map componentKeyToAdapterCache

componentAdapterFactory

private ComponentAdapterFactory componentAdapterFactory

parent

private PicoContainer parent

children

private java.util.Set children

componentAdapters

private java.util.List componentAdapters

orderedComponentAdapters

private java.util.List orderedComponentAdapters

started

private boolean started

disposed

private boolean disposed

childrenStarted

private java.util.Set childrenStarted

lifecycleManager

private LifecycleManager lifecycleManager

lifecycleStrategyForInstanceRegistrations

private LifecycleStrategy lifecycleStrategyForInstanceRegistrations
Constructor Detail

DefaultPicoContainer

public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory,
                            PicoContainer parent)
Creates a new container with a custom ComponentAdapterFactory and a parent container.

Important note about caching: If you intend the components to be cached, you should pass in a factory that creates CachingComponentAdapter instances, such as for example CachingComponentAdapterFactory. CachingComponentAdapterFactory can delegate to other ComponentAdapterFactories.

Parameters:
componentAdapterFactory - the factory to use for creation of ComponentAdapters.
parent - the parent container (used for component dependency lookups).

DefaultPicoContainer

public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory,
                            LifecycleStrategy lifecycleStrategyForInstanceRegistrations,
                            PicoContainer parent)
Creates a new container with a custom ComponentAdapterFactory, LifecycleStrategy for instance registration, and a parent container.

Important note about caching: If you intend the components to be cached, you should pass in a factory that creates CachingComponentAdapter instances, such as for example CachingComponentAdapterFactory. CachingComponentAdapterFactory can delegate to other ComponentAdapterFactories.

Parameters:
componentAdapterFactory - the factory to use for creation of ComponentAdapters.
lifecycleStrategyForInstanceRegistrations - the lifecylce strategy chosen for regiered instance (not implementations!)
parent - the parent container (used for component dependency lookups).

DefaultPicoContainer

public DefaultPicoContainer(ComponentMonitor monitor,
                            PicoContainer parent)
Creates a new container with the DefaultComponentAdapterFactory using a custom ComponentMonitor

Parameters:
monitor - the ComponentMonitor to use
parent - the parent container (used for component dependency lookups).

DefaultPicoContainer

public DefaultPicoContainer(ComponentMonitor monitor,
                            LifecycleStrategy lifecycleStrategy,
                            PicoContainer parent)
Creates a new container with the DefaultComponentAdapterFactory using a custom ComponentMonitor and lifecycle strategy

Parameters:
monitor - the ComponentMonitor to use
lifecycleStrategy - the lifecycle strategy to use.
parent - the parent container (used for component dependency lookups).

DefaultPicoContainer

public DefaultPicoContainer(LifecycleStrategy lifecycleStrategy,
                            PicoContainer parent)
Creates a new container with the DefaultComponentAdapterFactory using a custom lifecycle strategy

Parameters:
lifecycleStrategy - the lifecycle strategy to use.
parent - the parent container (used for component dependency lookups).

DefaultPicoContainer

public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory)
Creates a new container with a custom ComponentAdapterFactory and no parent container.

Parameters:
componentAdapterFactory - the ComponentAdapterFactory to use.

DefaultPicoContainer

public DefaultPicoContainer(ComponentMonitor monitor)
Creates a new container with the DefaultComponentAdapterFactory using a custom ComponentMonitor

Parameters:
monitor - the ComponentMonitor to use

DefaultPicoContainer

public DefaultPicoContainer(PicoContainer parent)
Creates a new container with a (caching) DefaultComponentAdapterFactory and a parent container.

Parameters:
parent - the parent container (used for component dependency lookups).

DefaultPicoContainer

public DefaultPicoContainer()
Creates a new container with a (caching) DefaultComponentAdapterFactory and no parent container.

Method Detail

getComponentAdapters

public java.util.Collection getComponentAdapters()
Description copied from interface: PicoContainer
Retrieve all the component adapters inside this container. The component adapters from the parent container are not returned.

Specified by:
getComponentAdapters in interface PicoContainer
Returns:
a collection containing all the ComponentAdapters inside this container. The collection will not be modifiable.
See Also:
a variant of this method which returns the component adapters inside this container that are associated with the specified type.

getComponentAdapter

public final ComponentAdapter getComponentAdapter(java.lang.Object componentKey)
Description copied from interface: PicoContainer
Find a component adapter associated with the specified key. If a component adapter cannot be found in this container, the parent container (if one exists) will be searched.

Specified by:
getComponentAdapter in interface PicoContainer
Parameters:
componentKey - the key that the component was registered with.
Returns:
the component adapter associated with this key, or null if no component has been registered for the specified key.

getComponentAdapterOfType

public ComponentAdapter getComponentAdapterOfType(java.lang.Class componentType)
Description copied from interface: PicoContainer
Find a component adapter associated with the specified type. If a component adapter cannot be found in this container, the parent container (if one exists) will be searched.

Specified by:
getComponentAdapterOfType in interface PicoContainer
Parameters:
componentType - the type of the component.
Returns:
the component adapter associated with this class, or null if no component has been registered for the specified key.

getComponentAdaptersOfType

public java.util.List getComponentAdaptersOfType(java.lang.Class componentType)
Description copied from interface: PicoContainer
Retrieve all component adapters inside this container that are associated with the specified type. The component adapters from the parent container are not returned.

Specified by:
getComponentAdaptersOfType in interface PicoContainer
Parameters:
componentType - the type of the components.
Returns:
a collection containing all the ComponentAdapters inside this container that are associated with the specified type. Changes to this collection will not be reflected in the container itself.

registerComponent

public ComponentAdapter registerComponent(ComponentAdapter componentAdapter)
Register a component via a ComponentAdapter. Use this if you need fine grained control over what ComponentAdapter to use for a specific component. This method can be used to override the ComponentAdapter created by the ComponentAdapterFactory passed to the constructor of this container.

Specified by:
registerComponent in interface MutablePicoContainer
Parameters:
componentAdapter - the adapter
Returns:
the same adapter that was passed as an argument.

unregisterComponent

public ComponentAdapter unregisterComponent(java.lang.Object componentKey)
Description copied from interface: MutablePicoContainer
Unregister a component by key.

Specified by:
unregisterComponent in interface MutablePicoContainer
Parameters:
componentKey - key of the component to unregister.
Returns:
the ComponentAdapter that was associated with this component.

registerComponentInstance

public ComponentAdapter registerComponentInstance(java.lang.Object component)
Register an arbitrary object. The class of the object will be used as a key. Calling this method is equivalent to calling * registerComponentImplementation(componentImplementation, componentImplementation). The returned ComponentAdapter will be an InstanceComponentAdapter.

Specified by:
registerComponentInstance in interface MutablePicoContainer
Returns:
the ComponentAdapter that has been associated with this component. In the majority of cases, this return value can be safely ignored, as one of the getXXX() methods of the PicoContainer interface can be used to retrieve a reference to the component later on.

registerComponentInstance

public ComponentAdapter registerComponentInstance(java.lang.Object componentKey,
                                                  java.lang.Object componentInstance)
Register an arbitrary object as a component in the container. This is handy when other components in the same container have dependencies on this kind of object, but where letting the container manage and instantiate it is impossible.

Beware that too much use of this method is an antipattern. The returned ComponentAdapter will be an InstanceComponentAdapter.

Specified by:
registerComponentInstance in interface MutablePicoContainer
Parameters:
componentKey - a key that identifies the component. Must be unique within the conainer. The type of the key object has no semantic significance unless explicitly specified in the implementing container.
componentInstance - an arbitrary object.
Returns:
the ComponentAdapter that has been associated with this component. In the majority of cases, this return value can be safely ignored, as one of the getXXX() methods of the PicoContainer interface can be used to retrieve a reference to the component later on.

registerComponentImplementation

public ComponentAdapter registerComponentImplementation(java.lang.Class componentImplementation)
Register a component using the componentImplementation as key. Calling this method is equivalent to calling registerComponentImplementation(componentImplementation, componentImplementation). The returned ComponentAdapter will be instantiated by the ComponentAdapterFactory passed to the container's constructor.

Specified by:
registerComponentImplementation in interface MutablePicoContainer
Parameters:
componentImplementation - the concrete component class.
Returns:
the ComponentAdapter that has been associated with this component. In the majority of cases, this return value can be safely ignored, as one of the getXXX() methods of the PicoContainer interface can be used to retrieve a reference to the component later on.

registerComponentImplementation

public ComponentAdapter registerComponentImplementation(java.lang.Object componentKey,
                                                        java.lang.Class componentImplementation)
Register a component. The returned ComponentAdapter will be instantiated by the ComponentAdapterFactory passed to the container's constructor.

Specified by:
registerComponentImplementation in interface MutablePicoContainer
Parameters:
componentKey - a key that identifies the component. Must be unique within the container. The type of the key object has no semantic significance unless explicitly specified in the documentation of the implementing container.
componentImplementation - the component's implementation class. This must be a concrete class (ie, a class that can be instantiated).
Returns:
the ComponentAdapter that has been associated with this component. In the majority of cases, this return value can be safely ignored, as one of the getXXX() methods of the PicoContainer interface can be used to retrieve a reference to the component later on.
See Also:
a variant of this method that allows more control over the parameters passed into the componentImplementation constructor when constructing an instance.

registerComponentImplementation

public ComponentAdapter registerComponentImplementation(java.lang.Object componentKey,
                                                        java.lang.Class componentImplementation,
                                                        Parameter[] parameters)
Register a component and creates specific instructions on which constructor to use, along with which components and/or constants to provide as constructor arguments. These "directives" are provided through an array of Parameter objects. Parameter[0] correspondes to the first constructor argument, Parameter[N] corresponds to the N+1th constructor argument.

Tips for Parameter usage


registerComponentImplementation

public ComponentAdapter registerComponentImplementation(java.lang.Object componentKey,
                                                        java.lang.Class componentImplementation,
                                                        java.util.List parameters)
Same as registerComponentImplementation(java.lang.Object, java.lang.Class, org.picocontainer.Parameter[]) but with parameters as a List. Makes it possible to use with Groovy arrays (which are actually Lists).


addOrderedComponentAdapter

private void addOrderedComponentAdapter(ComponentAdapter componentAdapter)

getComponentInstances

public java.util.List getComponentInstances()
                                     throws PicoException
Description copied from interface: PicoContainer
Retrieve all the registered component instances in the container, (not including those in the parent container). The components are returned in their order of instantiation, which depends on the dependency order between them.

Specified by:
getComponentInstances in interface PicoContainer
Returns:
all the components.
Throws:
PicoException - if the instantiation of the component fails

getComponentInstancesOfType

public java.util.List getComponentInstancesOfType(java.lang.Class componentType)
Description copied from interface: PicoContainer
Returns a List of components of a certain componentType. The list is ordered by instantiation order, starting with the components instantiated first at the beginning.

Specified by:
getComponentInstancesOfType in interface PicoContainer
Parameters:
componentType - the searched type.
Returns:
a List of components.

getComponentInstance

public java.lang.Object getComponentInstance(java.lang.Object componentKey)
Description copied from interface: PicoContainer
Retrieve a component instance registered with a specific key. If a component cannot be found in this container, the parent container (if one exists) will be searched.

Specified by:
getComponentInstance in interface PicoContainer
Parameters:
componentKey - the key that the component was registered with.
Returns:
an instantiated component, or null if no component has been registered for the specified key.

getComponentInstanceOfType

public java.lang.Object getComponentInstanceOfType(java.lang.Class componentType)
Description copied from interface: PicoContainer
Find a component instance matching the specified type.

Specified by:
getComponentInstanceOfType in interface PicoContainer
Parameters:
componentType - the type of the component
Returns:
an instantiated component matching the class, or null if no component has been registered with a matching type

getInstance

private java.lang.Object getInstance(ComponentAdapter componentAdapter)

getParent

public PicoContainer getParent()
Description copied from interface: PicoContainer
Retrieve the parent container of this container.

Specified by:
getParent in interface PicoContainer
Returns:
a PicoContainer instance, or null if this container does not have a parent.

unregisterComponentByInstance

public ComponentAdapter unregisterComponentByInstance(java.lang.Object componentInstance)
Description copied from interface: MutablePicoContainer
Unregister a component by instance.

Specified by:
unregisterComponentByInstance in interface MutablePicoContainer
Parameters:
componentInstance - the component instance to unregister.
Returns:
the ComponentAdapter that was associated with this component.

verify

public void verify()
            throws PicoVerificationException
Deprecated. since 1.1 - Use "new VerifyingVisitor().traverse(this)"

Description copied from interface: PicoContainer
Verify that the dependencies for all the registered components can be satisfied. No components are instantiated during the verification process.

Specified by:
verify in interface PicoContainer
Throws:
PicoVerificationException - if there are unsatisifiable dependencies.

start

public void start()
Start the components of this PicoContainer and all its logical child containers. The starting of the child container is only attempted if the parent container start successfully. The child container for which start is attempted is tracked so that upon stop, only those need to be stopped. The lifecycle operation is delegated to the component adapter, if it is an instance of lifecycle manager. The actual lifecycle strategy supported depends on the concrete implementation of the adapter.

Specified by:
start in interface Startable
See Also:
DefaultPicoContainer.OrderedComponentAdapterLifecycleManager, LifecycleStrategy, makeChildContainer(), addChildContainer(PicoContainer), removeChildContainer(PicoContainer)

stop

public void stop()
Stop the components of this PicoContainer and all its logical child containers. The stopping of the child containers is only attempted for those that have been started, possibly not successfully. The lifecycle operation is delegated to the component adapter, if it is an instance of lifecycle manager. The actual lifecycle strategy supported depends on the concrete implementation of the adapter.

Specified by:
stop in interface Startable
See Also:
DefaultPicoContainer.OrderedComponentAdapterLifecycleManager, LifecycleStrategy, makeChildContainer(), addChildContainer(PicoContainer), removeChildContainer(PicoContainer)

childStarted

private boolean childStarted(PicoContainer child)
Checks the status of the child container to see if it's been started to prevent IllegalStateException upon stop

Parameters:
child - the child PicoContainer
Returns:
A boolean, true if the container is started

dispose

public void dispose()
Dispose the components of this PicoContainer and all its logical child containers. The lifecycle operation is delegated to the component adapter, if it is an instance of lifecycle manager. The actual lifecycle strategy supported depends on the concrete implementation of the adapter.

Specified by:
dispose in interface Disposable
See Also:
DefaultPicoContainer.OrderedComponentAdapterLifecycleManager, LifecycleStrategy, makeChildContainer(), addChildContainer(PicoContainer), removeChildContainer(PicoContainer)

makeChildContainer

public MutablePicoContainer makeChildContainer()
Description copied from interface: MutablePicoContainer
Make a child container, using the same implementation of MutablePicoContainer as the parent. It will have a reference to this as parent. This will list the resulting MPC as a child. Lifecycle events will be cascaded from parent to child as a consequence of this.

Specified by:
makeChildContainer in interface MutablePicoContainer
Returns:
the new child container.

addChildContainer

public boolean addChildContainer(PicoContainer child)
Description copied from interface: MutablePicoContainer
Add a child container. This action will list the the 'child' as exactly that in the parents scope. It will not change the child's view of a parent. That is determined by the constructor arguments of the child itself. Lifecycle events will be cascaded from parent to child as a consequence of calling this method.

Specified by:
addChildContainer in interface MutablePicoContainer
Parameters:
child - the child container
Returns:
true if the child container was not already in.

removeChildContainer

public boolean removeChildContainer(PicoContainer child)
Description copied from interface: MutablePicoContainer
Remove a child container from this container. It will not change the child's view of a parent. Lifecycle event will no longer be cascaded from the parent to the child.

Specified by:
removeChildContainer in interface MutablePicoContainer
Parameters:
child - the child container
Returns:
true if the child container has been removed.

accept

public void accept(PicoVisitor visitor)
Description copied from interface: PicoContainer
Accepts a visitor that should visit the child containers, component adapters and component instances.

Specified by:
accept in interface PicoContainer
Parameters:
visitor - the visitor

changeMonitor

public void changeMonitor(ComponentMonitor monitor)
Changes monitor in the ComponentAdapterFactory, the component adapters and the child containers, if these support a ComponentMonitorStrategy. Changes the component monitor used

Specified by:
changeMonitor in interface ComponentMonitorStrategy
Parameters:
monitor - the new ComponentMonitor to use

currentMonitor

public ComponentMonitor currentMonitor()
Returns the first current monitor found in the ComponentAdapterFactory, the component adapters and the child containers, if these support a ComponentMonitorStrategy. Returns the monitor currently used

Specified by:
currentMonitor in interface ComponentMonitorStrategy
Returns:
The ComponentMonitor currently used
Throws:
PicoIntrospectionException - if no component monitor is found in container or its children