PicoContainer的工作流程

PicoContainer的工作流程

1、注册组件
客户端代码:
MutablePicoContainer pico = new DefaultPicoContainer();
pico.registerComponentImplementation(Boy.class);

通过下面方法注册组件:

    public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters){
        ComponentAdapter componentAdapter = componentAdapterFactory.createComponentAdapter(componentKey, componentImplementation, parameters);
        registerComponent(componentAdapter);
        return componentAdapter;
    }

我们先来看看registerComponent:

    public ComponentAdapter registerComponent(ComponentAdapter componentAdapter) {
        Object componentKey = componentAdapter.getComponentKey();
        if (componentKeyToAdapterCache.containsKey(componentKey)) {
            throw new DuplicateComponentKeyRegistrationException(componentKey);
        }
        componentAdapters.add(componentAdapter);
        componentKeyToAdapterCache.put(componentKey, componentAdapter);
        return componentAdapter;
    }
此方法用来注册注册组件,但是又不是直接把组件注册进去,而是通过ComponentAdapter进行了一次包装,也就是说,在ComponentAdapter中应该对组件有一些另外的描述。


现在再来看ComponentAdapter。
ComponentAdapter由其工厂componentAdapterFactory产生,而componentAdapterFactory其实是DefaultComponentAdapterFactory的实例。

public class DefaultComponentAdapterFactory implements ComponentAdapterFactory, Serializable {
    public ComponentAdapter createComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters){
        return new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(componentKey, componentImplementation, parameters));
    }
}

这样,我们就得到了一个CachingComponentAdapter的ComponentAdapter。但是,这个CachingComponentAdapter也不是最内部的那个ComponentAdapter。CachingComponentAdapter继承了DecoratingComponentAdapter,而DecoratingComponentAdapter使用了Decorate模式,其目的是为目标对象添加功能。CachingComponentAdapter类重写了DecoratingComponentAdapte的getComponentInstance方法,实现了缓存的功能:
    public Object getComponentInstance(PicoContainer container){
        if (instanceReference.get() == null) {
            instanceReference.set(super.getComponentInstance(container));
        }
        return instanceReference.get();
    }

由此可以看出,注册一个组件是注册了它的ComponentAdapter,而默认情况下,其实是最终注册了ConstructorInjectionComponentAdapter。


2、获取组件实例
客户端代码:
Girl girl = (Girl) pico.getComponentInstance(Girl.class);
girl.kissSomeone();

先来看getComponentInstance:
    public Object getComponentInstanceOfType(Class componentType) {
        final ComponentAdapter componentAdapter = getComponentAdapterOfType(componentType);
        return componentAdapter == null ? null : getInstance(componentAdapter);
    }

工作交给了getInstance:
    private Object getInstance(ComponentAdapter componentAdapter) {
 // ...
 Object instance = componentAdapter.getComponentInstance(this);
 // ...
 return instance;
 // ...
    }


有了上面的经验,这次就不罗嗦了,直捣黄龙,直接看ConstructorInjectionComponentAdapter的getComponentInstance方法:
 public Object getComponentInstance(PicoContainer container){

      // ...
      final Constructor constructor;
      constructor = getGreediestSatisfiableConstructor(guardedContainer);
      Object[] parameters = getConstructorArguments(guardedContainer, constructor);
      return newInstance(constructor, parameters);
      // ...
    }

这里就可以很明显的看出来了:先找到最合适(即可以使用最多参数)的构造子,然后设置其参数,最后生成一个实例返回给客户端。

 

posted on 2005-03-12 16:33  Na57  阅读(705)  评论(0编辑  收藏  举报