是不是值得深思?欢迎大家发表一下看法!
问题2.picocontainer中
MutablePicoContainer pico = new DefaultPicoContainer();
pico.registerComponentImplementation(Boy.class);
Boy boy = (Boy) pico.getComponentInstance(Boy.class);
谁知道Boy.class最终是在哪里,怎样被实例的?我看了半天看不出!谁知道,请教一下
谁知道Boy.class最终是在哪里,怎样被实例的?我看了半天看不出!谁知道,请教一下
2、跟踪getComponentInstance方法,很快就可以找到。
怎么可以实例?
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)才被实例化的。
万分感谢!!
seasabrina@gmail.com
急需!!