Skip to end of metadata
Go to start of metadata

Authors: Jörg Schaible

The code snippets use the classes from the Five Minute Introduction.

Basic Building Blocks of PicoContainer

Looking at a PicoContainer you can compare it to a simple hash map, that delivers a component instance when requesting one with a special key. While this is the simplistic view from the user's point of view, it is necessary to understand the internal building blocks of such a PicoContainer, that allows it to create new instances and resolving their dependencies and to be able to support all kind of components necessary to build a complex application.

A PicoContainer is actually very simple. All it knows about a single component is

  • the key
  • the general type if the key is a type
  • the real type of the component

With this information the PicoContainer can be requested for a component with a special key, for a component of a special type or for all components with a special type. Although the request is directed at the PicoContainer, it cannot instantiate any component by itself. This task is actually carried out by a ComponentAdapter. Such an adapter is created every time you register a component in a PicoContainer (actually in a MutablePicoContainer, since the PicoContainer interface is immutable):

An error occurred: http://svn.codehaus.org/picocontainer/java/picocontainer/trunk/container/src/test/org/picocontainer/doc/tutorial/blocks/BuildingBlocksTestCase.java. The system administrator has been notified.

 

Internally the PicoContainer has created two instances with the DefaultComponentAdapterFactory and one instance of a InstanceComponentAdapter (since the last component is an already existing object). You can also register such an adapter directly in the PicoContainer:

An error occurred: http://svn.codehaus.org/picocontainer/java/picocontainer/trunk/container/src/test/org/picocontainer/doc/tutorial/blocks/BuildingBlocksTestCase.java. The system administrator has been notified.

 

This code snippet also demonstrates, that the ComponentAdapter in fact also stores the component's key.

ComponentAdapter

As already explained it is the task of a ComponentAdapter to deliver an instance of a component. This might be an existing object as delivered by the InstanceComponentAdapter or in the standard case a created object. If a PicoContainer is requested for a component it will request in fact a component adapter with a component of the appropriate key or type to do so. The ComponentAdapter is also responsible to resolve all the dependencies of the component i.e. it will ask the requesting PicoContainer in return for any component it needs itself to resolve the components its own component is dependend on. This separation allows the implementation of different instantiation strategies as realized by the following ComponentAdapter implementations from the PicoContainer core package:

Aside form the instantiation strategy a lot of the ComponentAdapter implementations are delegators that are used for orthogonal functionality:

These adapters have a constructor taking another ComponentAdapter instance as argument and you might build a complex chain. Looking at the registry process in the PicoContainer, the following calls are equivalent:

  • Convenient:
An error occurred: http://svn.codehaus.org/picocontainer/java/picocontainer/trunk/container/src/test/org/picocontainer/doc/tutorial/blocks/BuildingBlocksTestCase.java. The system administrator has been notified.

 

  • At length:
An error occurred: http://svn.codehaus.org/picocontainer/java/picocontainer/trunk/container/src/test/org/picocontainer/doc/tutorial/blocks/BuildingBlocksTestCase.java. The system administrator has been notified.

 

ComponentAdapterFactory

The last code snippet has shown, that the PicoContainer automatically uses a cached ConstructorInjectionComponentAdapter. This is a reasonable default for service-oriented components using dependency injection. As you have already learned you can register a component with a different adapter (chain). But what if most of your service components have bean-style and need synchronization? This is a reasonable situation to change the ComponentAdapterFactory of the PicoContainer:

An error occurred: http://svn.codehaus.org/picocontainer/java/picocontainer/trunk/container/src/test/org/picocontainer/doc/tutorial/blocks/BuildingBlocksTestCase.java. The system administrator has been notified.

 

Following code is executed now, if a component is registered:

An error occurred: http://svn.codehaus.org/picocontainer/java/picocontainer/trunk/container/src/test/org/picocontainer/doc/tutorial/blocks/BuildingBlocksTestCase.java. The system administrator has been notified.

 

Other Container Elements

  • ComponentMonitor
  • Lifecycle

Usage patterns

Multiple ComponentAdapterFactories

In complex applications are build often with a lot of components, that can be grouped in different ways. Some will act as singletons in your application and might be registered using the default ComponentAdapterFactory of the PicoContainer, others must be created for each thread, the next are exposed with JMX and another group may be some EJBs to use. In such a case it is useful to create different ComponentAdapterFactory chains, that matches the needs of every group. Use these factories to create the ComponentAdapter instances and register them directly in the PicoContainer.

Labels
  • None