PicoContainer五分钟介绍/Five minute introduction

http://www.picocontainer.org/Five+minute+introduction

基础
这是对PicoContainer各个功能的一个快速介绍。阅读此文可以知道PicoContainer是什么。如果只是想得到一些代码来运行程序,请看《两分钟入门手册》。PicoContainer最重要的特性是可以实例化任何对象的能力。通过想使用Hash表一样简单的API,你可以把java.lang.Class对象放进去,把对象的实例取出来。
例如:
MutablePicoContainer pico = new DefaultPicoContainer();
pico.registerComponentImplementation(ArrayList.class);
List list = (List) pico.getComponentInstance(ArrayList.class);

这些代码跟下面这个是一样的:

List list = new ArrayList();

像这样的小例子还不足以说明PicoContainer的好处,这只是表明了最简单的API。当有大量的类和接口,并且互相依赖的时候就可以看出PicoContainer有多有用了。

Complex Dependencies Juicer Example

一个简单的类和对象相互依赖的例子

上面的“Juicer Example”的例子可以写做下面的代码:

public interface Peelable {
    void peel();
}

 

public class Apple implements Peelable {
    public void peel() {
    }
}

 

public class Peeler implements Startable {
    private final Peelable peelable;

    public Peeler(Peelable peelable) {
        this.peelable = peelable;
    }

    public void start() {
        peelable.peel();
    }

    public void stop() {

    }
}

 

public class Juicer {
    private final Peelable peelable;
    private final Peeler peeler;

    public Juicer(Peelable peelable, Peeler peeler) {
        this.peelable = peelable;
        this.peeler = peeler;
    }
}

 

装载组件:
MutablePicoContainer pico = new DefaultPicoContainer();
pico.registerComponentImplementation(Apple.class);
pico.registerComponentImplementation(Juicer.class);
pico.registerComponentImplementation(Peeler.class);

实例化组件:
Juicer juicer = (Juicer) pico.getComponentInstance(Juicer.class);

上面的代码与下面的代码实现同样的功能:
Peelable peelable = new Apple();
Peeler peeler = new Peeler(peelable);
Juicer juicer = new Juicer(peelable, peeler);
return juicer;

容器层次结构

PicoContainer对Singleton反模式提供了一种强大的选择机制。在容器中,你可以创建一个单态对象,然后很好地控制它的实例的可见范围(单态模式是静态和全局的,它最多允许一个对象存在,而且随处可见,这不是很好)。

一个容器可以操作其父容器中注册的组件,但反过来却不可以。看下面的例子:

// 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);

// Instantiate components
Peeler peeler = (Peeler) z.getComponentInstance(Peeler.class);
// WON'T WORK! peeler will be null
peeler = (Peeler) x.getComponentInstance(Peeler.class);
// WON'T WORK! This will throw an exception
Juicer juicer = (Juicer) y.getComponentInstance(Juicer.class

它将显示为以下的图形:


生命周期

PicoContainer对生命周期提供支持。如果你的组件实现Startable接口,你就在容器中可以通过简单的方法调用对其进行生命周期管理。容器将会判断出被它所管理的所有对象的start()/stop()方法的调用顺序。

当容器调用start()方法时,它会按照实例化对象的顺序对所有它管理的对象调用start()方法。也就是说,先实例化没有任何依赖的对象,最后才实例化依赖性很强的对象。

PicoContainer.start() PicoContainer.stop()


生命周期管理也可以在容器层次间进行,调用start()的时候,容器间遵循广度优先的调用顺序,相反,调用stop()的时候,则遵循深度优先原则。

PicoContainer.start() PicoContainer.stop()

注意:为了实现层级生命周期管理,子容器必须注册到父容器中。注册可以参考上面示例中y,z容器的声明,也可以使用如下方法:

直接注册:
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();

间接注册:
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();

posted on 2005-03-14 10:27  Na57  阅读(1172)  评论(0编辑  收藏  举报