目的:
不拘泥与具体细节,对spring bean的生成能有一个整体的把握。
图片整体预览
正文
spring bean
的生成主要分为两个阶段,第一个是bean Definition
的生成
,第二个是bean的生成。也就是本文的主要内容。
对于spring
实例初始一个bean
,我们主要分析一下几点
- 子类
beanDefinition
合并父类bean Definition
的一些数据; bean
实例化之前的操作介绍resolveBeforeInstantiation
(产生代理的时机)- 实例化bean的几种方式
createBeanInstance
- 工厂方法创建
- 带参数的构造方法创建
- 默认的构造方法创建
- 注入数学过程如何解决循环依赖
bean
实例化后属性的装填工作populateBean
- 名称注入
- 类型注入
- 初始化
bean initializeBean
方法调用- 处理 bean 的前置处理器
- 执行 init-method 方法
- 处理 bean 的后置处理器
以上几点是按照上图,方法的调用顺序依次介绍。也是bean
生成过程的顺序介绍。
子类beanDefinition
合并父类bean Definition
的一些数据;
这块主要是图片中这部分的介绍
子类的bean因为是继承了父类bean,所以在创建子类时需要合并一些父类的属性到子类中,主要是getMergedLocalBeanDefinition()
这个方法不是很重要,这里就不贴源码占用大家时间了。
bean
实例化之前的操作介绍resolveBeforeInstantiation
(产生代理的时机)
这个小结主要介绍的是下图这块的内容
贴个入口代码
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
我们创建代理是通过一个后置处理器
实例化bean的几种方式 createBeanInstance
- 工厂方法创建
- 带参数的构造方法创建
- 默认的构造方法创建
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
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);//默认的构造方法创建
}
}
bean
实例化后属性的装填工作populateBean
属性的依赖注入就是在这个阶段,比如通过Autowire注入这种。同样我们这里重点分析循环依赖。
注入过程如何解决循环依赖
A依赖B、B依赖A 形成一个依赖环。spring的解决方案是,实例化A,之后将A封装到一个ObjectFactory
对象中存储。对A进行属性填充的时候,发现有B需要实例化,则去实例化B,实例化B的时候也会将B封装到一个ObjectFactory
对象中存储。B实例化完之后,会去填充B的属性,这是发现有A属性需要填充,这是不再会去创建A而是从封装了A对象的ObjectFactory中直接取。从而完成B的属性填充,继而完成了A的属性填充。更加完善的源码分析,可以参考文章
初始化bean initializeBean
方法调用
- 处理
bean
的前置处理器 - 执行
init-method
方法 - 处理
bean
的后置处理器
这里要补充下bean
的后置处理器,后置处理器在spring
中是非常强大的,可以处理很多事。不仅仅是bean
的初始化中对bean修改,同时在上一小节中的属性注入也是这通过autowireBeanPostProcessor进行注入。spring将很多小功能拆给了一个后置处理器来处理。系统就非常灵活了。
进入initializeBean的过程
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
//调用一些aware方法注入一些系统的属性到bean中
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//bean 前置处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用bean init方法
wrappedBean =
invokeInitMethods(beanName, wrappedBean, mbd);
}
if (mbd == null || !mbd.isSynthetic()) {
//对bean进行一些后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
以上对于getBean
的流程基本分析完,后序会征对spring
的一些细节进一步深入分析。
转载:https://blog.csdn.net/ygy982883422/article/details/105758616
查看评论