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