Title: PicoContainer
1PicoContainer
- Presented by
- Jim OHara
- Ed Kausmeyer
- Jingming Zhang
2Lightweight Containers
- Attempts to build alternatives to the mainstream
J2EE technologies - A common obstacle
- How to wire together different elements
- How do you fit together this web controller
architecture with that database interface backing
when they were built by different teams with
little knowledge of each other? - Lightweight Containers
- Frameworks that have taken a stab at this problem
and are branching out to provide a general
capability to assemble components from different
layers - PicoContainer, Spring
3Overview of PicoContainer
- Lightweight and highly embeddable container for
components that honor Dependency Injection - Small, simple container for arbitrary
components/services - Originally implemented in Java
- Now available for other platforms and languages
also (including C and Ruby) - http//opensource.thoughtworks.com/projects/picoco
ntainer.jsp
4Overview of PicoContainer
- Not a replacement for a J2EE container
- Does not offer any infrastructure services out of
the box - Can use the monitor support of PicoContainer to
react on internal events e.g. by logging
5Benefits of PicoContainer
- Embeddable inside other applications
- 50k jar that has no external dependencies except
JDK 1.3 - Compact in size
- Non-intrusive
- Components don't have to implement any funny APIs
and can be POJOs - Very extensible design Enables virtually any
form of extensions to the core
6Benefits of PicoContainer
- Modularize how dependencies between parts of an
application are laced up - Common to have dependencies scattered all over
- Can be valuable for large projects
- Improve how components are configured in an
application - Improve the testability of code
7Dependency Injection
- A way of instantiating components and lacing them
together with other dependent components - Main idea Have a separate object, an assembler,
that populates a field in a class to be created
with an appropriate implementation for an
interface that class needs, resulting in a
dependency - That is, a component user specifies the
interfaces it needs, and the implementations of
the required components are provided at creation
time - Decouple the caller of the component from the
implementation
8Types of Dependency Injection
- Constructor Dependency Injection (CDI) an object
gets all its dependencies via the constructor - Setter Dependency Injection (SDI) the container
or embedder hands dependencies to a component via
setter methods after instantiation
9Dependency Injection In PicoContainer
- PicoContainer supports CDI and SDI
- PicoContainer identifies dependencies by looking
at the constructors of registered classes (CDI) - PicoContainer can be thought of as a generic
factory that can be configured dynamically - PicoContainer is able to instantiate a complex
graph of several interdependent objects
10Components In PicoContainer
- Components are implemented as ordinary Java
classes and do not typically have to rely on any
PicoContainer APIs - The components are assembled in a container using
a simple Java API that is similar to an
intelligent hash map utilizing the type of its
values - This allows PicoContainer to instantiate
arbitrary objects - You can put java.lang.Class objects in and get
object instances back
11Components In PicoContainer
- A component user specifies the interfaces it
needs, and PicoContainer provides the
implementations of the required components at
creation time - This is what Dependency Injection is all about
- A component can be used in the PicoContainer
without importing or extending any interfaces or
defined in the PicoContainer assembly
12Demonstration Juicer Example
- Example taken from http//www.picocontainer.org/Fi
veminuteintroduction
13Container Hierarchies
- Containers provide a powerful alternative to the
singleton antipattern - The singleton pattern is static and global it
won't allow more than one instance and is visible
from anywhere - Containers serve as singleton-like objects that
provide fine-grained control over the visibility
scope of the instance
14Container Hierarchies
- A container (and its registered components) can
get access to components registered in a parent
container, but not vice-versa
15- //Container Hierarchy Example
- // Create x hierarchy of containers
- MutablePicoContainer x new DefaultPicoContainer(
) - MutablePicoContainer y new DefaultPicoContainer(
x) - MutablePicoContainer z new DefaultPicoContainer(
x) - // Assemble components
- x.registerComponentImplementation(Apple.class)
- y.registerComponentImplementation(Juicer.class)
- z.registerComponentImplementation(Peeler.class)
16- //Container Hierarchy Example Continued
- // Instantiate components
- Peeler peeler (Peeler)z.getComponentInstance(Pee
ler.class) - // WON'T WORK! peeler will be null
- peeler (Peeler) x.getComponentInstance(Peeler.cl
ass) - // WON'T WORK! This will throw an exception
- Juicer juicer (Juicer)y.getComponentInstance(Jui
cer.class)
- First line will work fine z will be able to
resolve the dependencies for Peeler (which is
Apple) from the parent container - Second line will return null, as x can't see
Peeler - Third line will throw an exception, since
Juicer's dependency to Peeler can't be satisfied
(z can't be seen by y)
17Lifecycle
- One third of Inversion of Control
- Inversion of Control dependency resolution
configuration lifecycle - Concerns the post composition life of a component
- Most commonly encountered lifecycle concepts
start, stop, dispose
18Lifecycle
- The lifecycle of components are easy to manage in
PicoContainer - Lifecycle callbacks are supported by implementing
the lifecycle interfaces - PicoContainer provides two simple interfaces for
lifecycle Startable and Disposable - A lifecycle can be extended or totally customized
19Lifecycle
- If a set of classes implement Startable, the
lifecycle of all the objects can be controlled
with method calls on the container - The container will figure out the correct order
of invocation of start() or stop() for all the
objects it manages
20Lifecycle
- Calling start() on the container will call stop()
on all container-managed objects in the order of
their instantiation - This means starting with the ones that have no
dependencies, and ending with the ones that have
dependencies on others
21Lifecycle
- Calling start() on a container with child
containers will start all the containers in a
breadth-first order, starting with itself - Likewise, calling stop() will call stop() on all
containers in the hierarchy in a depth-first order
22Lifecycle
- In order for a hierarchy-aware lifecycle to work,
child containers must be registered as components
in their parent container - Just creating a container with another one as a
parent will not cause the parent container to
know about the child container - Calling lifecycle methods on a child container
will not propagate the lifecycle to its parent
container
23Lifecycle Example A Direct Approach
- MutablePicoContainer parent new
DefaultPicoContainer() - MutablePicoContainer child new
DefaultPicoContainer(parent) - // We must let the parent container know
- // about the child container.
- parent.registerComponentInstance(child)
- // This will start the parent, which
- // will start the child.
- parent.start()
24Lifecycle Example An Indirect Approach
- MutablePicoContainer parent new
DefaultPicoContainer() - parent.registerComponentImplementation("child",
DefaultPicoContainer) - // This will instantiate the child container
- // passing the parent (itself) as parent
- // container.
- // No need to register the child in the parent
- // here.
- MutablePicoContainer child (MutablePicoContainer
) parent.getComponentInstance("child") - // This will start the parent, which will start
- // the child.
- parent.start()
25NanoContainer, for expanding capabilities
- Builds on top of PicoContainer the support for
several scripting metalanguages (XML, Groovy,
Bsh, Javascript and Jython), AOP, Web frameworks
(Struts and WebWork), SOAP, JMX, and much more
26Example
27(No Transcript)
28- import org.picocontainer.
- import org.picocontainer.defaults.
- public class DITest
- public static void main(String args)
- //Two ways to test Inversion of
Control in pico container - //Both use Dependency Injection
Patten. - //Constructor Injection with
PicoContainer indirectly - System.out.println("Constructor Injection
indirectly") - MyMovieFinder mmf new MyMovieFinder()
- mmf.testWithPico()
- //Constructor Injection with
PicoContainer directly - System.out.println("constructor Injection
directly") - MutablePicoContainer pico new
DefaultPicoContainer() - pico.registerComponentImplementation(MovieFinderI
mpl.class) - pico.registerComponentImplementation(MovieLister.
class)
29Output of Executing DITest Class
- F\SE510gtjava DITest
- Constructor Injection indirectly
- MovieFinder was listed by MovieLister_at_1cfb549
- constructor Injection directly
- MovieFinder was listed by MovieLister_at_186d4c1
- Construct Object without PicoContainer
- MovieFinder was listed by MovieLister_at_f9f9d8
30References
- Page with several links for information about
PicoContainerhttp//www.picocontainer.org/ - One-minute description provides an overview of
PicoContainer and lists some of its
benefitshttp//www.picocontainer.org/Oneminuted
escription - Two minute tutorial provides code snippets that
serve as a introduction to PicoContainerhttp//ww
w.picocontainer.org/Twominutetutorial - Five minute introduction provides code snippets
that serve as a introduction to PicoContainer and
explains the concepts of container hierarchies
and lifecyclehttp//www.picocontainer.org/Fivemi
nuteintroduction - Paper Inversion of Control Containers and the
Dependency Injection patternhttp//www.martinfowl
er.com/articles/injection.html - Constructor Dependency Injection with
PicoContainer, a post-J2EE Nirvana Explains
Inversion of Control (IoC) and Constructor
Dependency Injection (CDI) in PicoContainer and
NanoContainerhttp//conferences.oreillynet.com/cs
/os2004/view/e_sess/5294