谁研究过picocontainer 进来讨论一下!

04-07-26 nickycy
问题1.我觉得国人写的代码和老外写的代码风格真很不一样为什么?

是不是值得深思?欢迎大家发表一下看法!

问题2.picocontainer中

MutablePicoContainer pico = new DefaultPicoContainer();

pico.registerComponentImplementation(Boy.class);

Boy boy = (Boy) pico.getComponentInstance(Boy.class);

谁知道Boy.class最终是在哪里,怎样被实例的?我看了半天看不出!谁知道,请教一下

anonymous
2004-07-27 09:11
1、我没觉得有什么不一样的。大家看的都是同样的书,怎么会有多大的风格差异?

2、跟踪getComponentInstance方法,很快就可以找到。

nickycy
2004-07-27 09:40
1。new DefaultPicoContainer()的时候主要是new了DefaultComponentAdapterFactory

2。在regedit的时候用DefaultComponentAdapterFactory创建相关的adapter,同时把boy.class作为参数传入,我跟踪最终好象保存在AbstractComponentAdapter里面,我想regedit阶段boy.class是没有被实例的

3。调用getComponentInstance的时候最终也跟踪到最终的也是调用了getComponentInstance的方法,里面没有boy.class.newinstance()或new boy()的方法啊,那怎么实例?还有第三种实例方式?不可以调用接口的getComponentInstance就能实现吧。8明白什么回事

nickycy
2004-07-27 09:45
在ComponentAdapter接口里有这样的方法和注释

/**

* Retrieve the component instance. This method will usually create a new instance each time it is called, but that

* is not required. For example, {@link org.picocontainer.defaults.CachingComponentAdapter} will always return the

* same instance.

*

* @return the component instance.

* @throws PicoInitializationException if the component could not be instantiated.

* @throws PicoIntrospectionException if the component has dependencies which could not be resolved, or

* instantiation of the component lead to an ambigous situation within the

* container.

*/

Object getComponentInstance() throws PicoInitializationException, PicoIntrospectionException;

怎么可以实例?

nickycy
2004-07-27 10:30
怎么调用接口也能实例,邪!

nickycy
2004-07-27 10:49
哈哈,原来是用反射实例的。。哈哈,转了几百个弯实例是这个方法constructor.newInstance(parameters)

banq
2004-07-27 10:59
Picocontainer主要是使用JDKAPI的Constructor的newInstance方法生成Boy.class这样的实例的。

DefaultContainer的getComponentInstance是委托给componentAdapter.getComponentInstance()实现的

那么关键是componentAdapter中肯定已经有了Boy.class实例了。

下面回头从如何注册Boy.class角度看:

Boy.class是通过registerComponentImplementation方法进入PicoContainer的

这个方法很重要代码如下:

public ComponentAdapter registerComponentImplementation(Object componentKey,

Class componentImplementation,

Parameter[] parameters) throws PicoRegistrationException {

ComponentAdapter componentAdapter =

componentAdapterFactory.createComponentAdapter(componentKey, componentImplementation, parameters);

registerComponent(componentAdapter);

return componentAdapter;

}

上面使用了componentAdapterFactory.createComponentAdapter方法创建了componentAdapter,那么Boy.class

实例化是在componentAdapterFactory中实现了,componentAdapterFactory有很多子类,打开其一个子类看看

public class DefaultComponentAdapterFactory implements ComponentAdapterFactory, Serializable {

public ComponentAdapter createComponentAdapter(Object componentKey,

Class componentImplementation, Parameter[] parameters)

throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {

return new CachingComponentAdapter(

new ConstructorInjectionComponentAdapter(componentKey, componentImplementation, parameters));

}

}

createComponentAdapter方法返回了一个实例ConstructorInjectionComponentAdapter, 关键就在

ConstructorInjectionComponentAdapter中,ConstructorInjectionComponentAdapter是

InstantiatingComponentAdapter子类

看看InstantiatingComponentAdapter中有一个public Object getComponentInstance()方法,

这个方法实现了Boy.class的实例。

注意,前面提到:DefaultContainer的getComponentInstance是委托给componentAdapter.getComponentInstance()实现的

InstantiatingComponentAdapter的getComponentInstance()实际是componentAdapter的getComponentInstance()一个具体

实现。

两军会师,直捣黄龙,打开InstantiatingComponentAdapter的getComponentInstance()方法代码:

这个方法实际调用下面一句:

Object instance = instantiateComponent(adapterInstantiationOrderTrackingList);

可见,instance实例又是由 instantiateComponent实现,而instantiateComponent是InstantiatingComponentAdapter

的抽象方法,跟踪到这里似乎失去方向,但是别忘记它的子类ConstructorInjectionComponentAdapter

instantiateComponent方法中主要获得一个constructor实例,如下:

Constructor constructor = getGreediestSatisifableConstructor(adapterInstantiationOrderTrackingList);

然后通过newInstance获得实例,如下

return newInstance(constructor, parameters);

newInstance又是父类InstantiatingComponentAdapter的方法如下:

protected Object newInstance(Constructor constructor, Object[] parameters)

throws InstantiationException, IllegalAccessException, InvocationTargetException {

if (allowNonPublicClasses) {

constructor.setAccessible(true);

}

return constructor.newInstance(parameters);

}

终于找到源头了。

可见,Boy.class是在客户端调用getComponentInstance(Boy.class)才被实例化的。

nickycy
2004-07-27 11:58
我虽然也刚明白了实例过程,但还是非常感激bang作了详细讲解!

firebird
2006-05-24 11:57
求助 picocontainer 的网站上不去呀,谁有picocontainer 能Email给我吗?

万分感谢!!

seasabrina@gmail.com

急需!!

猜你喜欢