接上篇文章:Bean创建流程一(源码分析)
总体步骤:
1. 实例化(Instantiation)
2. 属性填充(Populate)
3. 初始化(Initialization)
4. 销毁(Destruction)
先上简单流程图:
1.实例化阶段:
进入关键方法:
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//实例化bean的关键步骤createBeanInstance
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
核心方法:**createBeanInstance** 方法内核心的步骤已在代码中做出了注释
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a BeanWrapper for the new instance
* @see #obtainFromSupplier
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
* @see #instantiateBean
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 确认 Bean 此时是否已经被解析了
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());
}
// 如果 Bean 提供 Supplier ⽅法,则⽤此策略进⾏实例化
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果当前Bean实现了FactoryBean接⼝则调⽤对应的FactoryBean接⼝的getObject⽅法
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 判断该bean是否重复创建 如果重复创建 则直接调用对应的方法
//为什么会有重复创建 Bean 的情况?因为⼀般情况我们的 Bean 的作⽤域都是 Singleton 的,但是在⾮Singleton 的情况下,我们⽆需每次都要去经过⼀系列的判断来确定实例化策略,直接使⽤上次解析过的、在 BeanDefinition 中的数据即可。
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);
}
}
// Candidate constructors for autowiring?
// 自动装配的候选构造函数