`

IOC英文讲解

 
阅读更多

Introduction

Authors: Aslak Hellesoy, Jon Tirsen

Basics

This 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 API, which is similar to a hash table. You can put java.lang.Class objects in and get object instances back.

Example:

MutablePicoContainer pico = new DefaultPicoContainer();
pico.addComponent(ArrayList.class); 
List list = pico.getComponent(ArrayList.class);

(i) MutablePicoContainer API

This code does the same as this:

List list = new ArrayList();

With a trivial example such as this there is no point in using PicoContainer. This was just to illustrate the basic API. PicoContainer becomes useful with larger number of classes and interfaces having complex dependencies between each other:

Complex Dependencies Juicer Example

(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 dependencies

The “Juicer Example” diagram above could translate to the following code (we added a concrete Peelable):

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; 
  } 
}

(Note that this code suffers from the anti-pattern Propagating Dependency but let’s not worry about that for now )

Assemble components

You tell PicoContainer what classes to manage by registering them like this (the order of registration has no significance):

MutablePicoContainer pico = new DefaultPicoContainer();
pico.addComponent(Apple.class);
pico.addComponent(Juicer.class);
pico.addComponent(Peeler.class);

(i) MutablePicoContainer API

Instantiate components

You can tell PicoContainer to give you an instance of a class like this (provided it has been registered previously):

Juicer juicer = (Juicer) pico.getComponent(Juicer.class);

This will cause PicoContainer to do something similar to this behind the scenes (except that PicoContainer uses reflection):

Peelable peelable = new Apple(); 
Peeler peeler = new Peeler(peelable); 
Juicer juicer = new Juicer(peelable, peeler); 
return juicer;

Note how PicoContainer figures out that Apple is a Peelable, so that it can be passed to Peeler and Juicer’s constructors.

Container hierarchies

PicoContainer 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:

THIS WON’T WORK! It is for illustration purposes only!

// Create x hierarchy of containers 
MutablePicoContainer x = new DefaultPicoContainer();
MutablePicoContainer y = new DefaultPicoContainer( x ); 
MutablePicoContainer z = new DefaultPicoContainer( y ); 
// Assemble components
x.addComponent(Apple.class); 
y.addComponent(Juicer.class); 
z.addComponent(Peeler.class); 
// Instantiate components 
Peeler peeler = (Peeler) z.getComponent(Peeler.class); // WON'T WORK! peeler will be null 
peeler = (Peeler) x.getComponent(Peeler.class); // WON'T WORK! This will throw an exception 
Juicer juicer = (Juicer) y.getComponent(Juicer.class);

This can be visualised as follows:

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 .

Lifecycle

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.

Example

MutablePicoContainer parent = new DefaultPicoContainer(new Caching()); 
MutablePicoContainer child = new DefaultPicoContainer(parent); // We must let the parent container know about the child container. 
parent.addComponent(child); // This will start the parent, which will start the child. 
parent.start();

Lifecycle is really only going to work for PicoContainers that are also caching component instances. Caching was a default in PicoContainer 1.x, but is not for 2.x – be warned!

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 Styles

With 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);
分享到:
评论

相关推荐

    springioc的详细讲解

    spring的ioc容器详细讲解,理解springioc容器

    Spring IoC加载流程讲解

    Spring IoC加载流程讲解以及IoC思想和依赖倒置原则

    Ioc注入讲解

    一篇关于从java技术层面介绍容器注入的文档,值得推荐!

    Spring IoC讲解PPT

    Spring讲解PPT,了解Spring的起源历史,Ioc、AOP等知识。

    IOC控制反转机制的讲解

    详细讲解ioc控制反转机制,供大家深入了解ioc机制

    IOC详解IOC详解IOC详解IOC详解

    IOC详解IOC详解IOC详解IOC详解IOC详解IOC详解IOC详解IOC详解

    自己动手实现IOC和MVC源码

    在自己博客里自己动手实现IOC和MVC系列中的全部源码 http://blog.csdn.net/ajun_studio/article/details/6831241

    spring_aop_ioc完全讲解

    spring.doc spring.doc spring.docspring.doc spring.doc spring.doc spring.doc spring.doc

    Java IoC讲解

    Ioc,使用容器按需要创建对象,避免了在对象中new 对象的高耦合...........

    spring ioc和aop讲解项目demo

    通过项目实例详细讲解spring的IOC和AOP思想,通俗易懂的项目demo

    IoC对象实例IoC对象实例

    IoC对象实例IoC对象实例IoC对象实例

    IOC模式 c#经典例子

    IOC模式 c#经典例子 IOC 例子 IOC模式 c#经典例子 IOC 例子 IOC模式 c#经典例子 IOC 例子

    Springioc注入Demo

    详细讲解了springioc的各种注入方式以及对应的java方式。讲解了springioc和DI的区别,以及注入特殊复杂的属性

    springIoc实现原理

    spring ioc指的是控制反转,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。交由Spring容器统一进行管理,从而实现松耦合

    spring Ioc容器配置

    spring Ioc容器配置 IOC容器数据源配置 <!-- 配置数据源 --> destroy-method="close"> <value>org.gjt.mm.mysql.Driver <value>jdbc:mysql://localhost:3306/demo <value>root ...

    SpringIoC的简单实现

    我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC的原理和源码。 详细内容见博文: 【SSH进阶之路】一步步重构容器实现Spring的IoC——从一个...

    spring ioc.jar

    spring ioc.jar springioc必备开发工具包

    SpringIoc示例代码

    SpringIoc示例代码,SpringIoc示例代码,SpringIoc示例代码,SpringIoc示例代码

    Spring中IoC优点与缺点解析

    主要为大家详细解析了Spring中IoC优点与缺点,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    Spring通过注解实现IOC

    Spring通过注解实现IOC,Spring通过注解实现IOC,Spring通过注解实现IOC

Global site tag (gtag.js) - Google Analytics