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

问题1.我觉得国人写的代码和老外写的代码风格真很不一样为什么?
是不是值得深思?欢迎大家发表一下看法!
问题2.picocontainer中
MutablePicoContainer pico = new DefaultPicoContainer();
pico.registerComponentImplementation(Boy.class);
Boy boy = (Boy) pico.getComponentInstance(Boy.class);

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

1、我没觉得有什么不一样的。大家看的都是同样的书,怎么会有多大的风格差异?

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

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明白什么回事

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

怎么可以实例?

怎么调用接口也能实例,邪!

哈哈,原来是用反射实例的。。哈哈,转了几百个弯实例是这个方法constructor.newInstance(parameters)

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)才被实例化的。



我虽然也刚明白了实例过程,但还是非常感激bang作了详细讲解!

求助 picocontainer 的网站上不去呀,谁有picocontainer 能Email给我吗?

万分感谢!!

seasabrina@gmail.com

急需!!