IOC英文讲解
Introduction
Authors: Aslak Hellesoy, Jon Tirsen
BasicsThis is a quick introduction to PicoContainer’s most important features. Read through it to get an idea of what PicoContainer is and isn’t.
PicoContainer’s most important feature is its ability to instantiate arbitrary objects. This is done through its
(Green means class, Yellow means interface). PicoContainer identifies dependencies by looking at the constructors of registered classes ( Constructor Injection ). PicoContainer can also be though of as a generic factory that can be configured dynamically. PicoContainer is able to instantiate a complex graph of several interdependent objects.
Write some simple classes and interfaces with dependenciesThe “Juicer Example” diagram above could translate to the following code (we added a concrete Peelable):
You tell PicoContainer what classes to manage by registering them like this (the order of registration has no significance):
Note how PicoContainer figures out that Apple is a Peelable, so that it can be passed to Peeler and Juicer’s constructors.Container hierarchiesPicoContainer provides a powerful alternative to the Singleton . With container hierarchies you can create singleton-like objects where you have fine grained control over the visibility scope of the instance. (The singleton pattern is static and global it won’t allow more than one instance, and it is visible from anywhere. Not nice when you try to build a large enterprise application from it).
A container (and its registered components) can get access to components registered in a parent container, but not vice-versa. Consider this example, using the classes from above:
Let’s analyse what will happen here:
Line 12 will work fine. z will be able to resolve the dependencies for Peeler (which is Fruit) from the parent container. Line 14 will return null, as x can’t see Peeler. Line 16 will throw an exception, since Juicer’s dependency to Peeler can’t be satisfied (z can’t be seen by y). Since this obviously won’t work, keep in mind that this was just an exercise to illustrate how container hierarchies work.
For a more concrete example of the usage of container hierarchies, see PicoContainer Web .
PicoContainer has support for Lifecycle . If your classes implement Startable , you can control the lifecycle of all your objects with a simple method call on the container. The container will figure out the correct order of invocation of start()/stop() all the objects managed by the container.
Calling start() on the container will call start() 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:
MutablePicoContainer.start() MutablePicoContainer.stop()!

Lifecycle also works for hierarchies of containers. 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. The pictures below show what happens when start() and stop() are called on a container with children.
MutablePicoContainer.start() MutablePicoContainer.stop()

In order for 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 container that has a parent container will not propagate the lifecycle to the parent container.
Read more about lifecycle here .
Contrasting Usage StylesWith PicoContainer you add components and get instances out in two styles.
Classic bean style:
pico = new DefaultPicoContainer();pico.addComponent(ComponentOneImpl.class) // by type pico.addComponent(ComponentTwoImpl.class) // by type pico.addComponent(new ComponentThreeImpl()) // by instance pico.addComponent(ComponentFourImpl.class) // by type ComponentFourImpl four = pico.getComponent(ComponentFourImpl.class);
Or you can use a fluent style if you want:
ComponentFour four = new DefaultPicoContainer().addComponent(ComponentOne.class) .addComponent(ComponentTwo.class).addComponent(new ComponentThree()) .addComponent(ComponentFour.class).getComponent(ComponentFour.class);