今天继续对Spring加载bean的相关进行了了解。
会发现在getBean()操作的时候,有一段代码.如果是单实列的话,没有找到的话,会进行createBean。
if (mbd.isSingleton()) {
// 第二个getSingleton,更倾向于创建
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
于是对这里的createBean()方法进行了解。
在这个方法中,先对class进行了判断,只对class是非公开开心的才可以创建。
// 三个条件表达的意思是: mbd 中如果nonPublicAccessAllowed字段的值为true,
// 表示class是非公开类型的,也可以创建实列。反之false。说明是无法创建。
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());
}
继续往下,有两个属性.
// 表示bd对应的构造信息是否已经解析成可以反射调用的构造方法method信息了
boolean resolved = false;
// 是否自动匹配构造方法
boolean autowireNecessary = false;
在接下来的逻辑中, 是对autowireNecessary进行处理
// 条件成立,说明bd的构造信息已经转换成可以反射调用的method了。
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
//当resolvedConstructorOrFactoryMethod 有值时,且构造方法有参数,那么可以认为这个字段值就是true
// 只有什么情况下该字段为false?
// 1. resolvedConstructorOrFactoryMethod == null
// 2.当resolvedConstructorOrFactoryMethod 表示的是默认的构造方法,无参构造方法。
autowireNecessary = mbd.constructorArgumentsResolved;
}
有了resolved的值,会进行对应的处理。
if (resolved) {
if (autowireNecessary) {
// 有参数,就需要根据参数 去匹配合适的构造方法
// 拿出当前Class的所有构造器,然后根据参数信息 去匹配一个最优的选项
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 无参构造方法处理
return instantiateBean(beanName, mbd);
}
}