我们一般是通过调用一个类的构造函数完成实例化的工作,spring当然也不例外。然而相比于直接通过构造函数对类进行实例化,spring的实例化过程要复杂得多。
在之前的博客中,本人曾经说过,任何一个JavaBean都有一个beandefinition。然而beandefinition并没有规定一个类的构造函数是哪个。原因很简单,因为在xml文件中没有规定构造函数的方法。spring只能通过<constructor-arg/>标签中的信息去“猜测”哪一个构造函数最合适。而“猜测构造函数”这个工作并不适合在构建beandefinition时完成,其更适合在实例化JavaBean的时候进行。在合适的时间做合适的事情,spring很好地把握了这一点。
spring通过AbstractAutowireCapableBeanFactory类中的createBeanInstance完成类的实例化。其代码如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
Class beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
对于被<constructor-arg/>修饰的JavaBean,其最终归宿是在autowireConstructor这个函数中,而该函数则调用了其他类的autowireConstructor,而该方法的具体实现如下所示。
public BeanWrapper autowireConstructor(
final String beanName, final RootBeanDefinition mbd, Constructor[] chosenCtors, final Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArgumen