Spring启动过程——源码分析(finishBeanFactoryInitialization(beanFactory))

前言

此篇是补充上篇未分析完的finishBeanFactoryInitialization部分
配合上篇食用效果更佳

Spring启动过程——源码分析

finishBeanFactoryInitialization(beanFactory)

主要方法preInstantiateSingletons()
遍历List beanNames
如果Bean 不是抽象&是单例&不是lazy

如果不是FactoryBean

getBean进入doGetBean 下面四张图都是
doGetBean.1

doGetBean.2
doGetBean.3
doGetBean.4
如果是bean是单例
重点方法 getSingleton
大致执行如下

   //先从缓存中取 第一次进来时没有值的
   Object singletonObject = this.singletonObjects.get(beanName);
   //存在 则return
   if(singletonObject!=null) return;
   //解决循环依赖
   beforeSingletonCreation(beanName);
   //真正创建bean
   singletonObject = singletonFactory.getObject();
   afterSingletonCreation(beanName);
   //加入缓存
   addSingleton(beanName, singletonObject);
   return singleObject
复制代码

真正创建Bean是createBean() 如果是bean是多例

    //this.prototypesCurrentlyInCreation.set(beanName)
    beforePrototypeCreation(beanName);  
    prototypeInstance = createBean(beanName, mbd, args);
    //this.prototypesCurrentlyInCreation.remove()
    afterPrototypeCreation(beanName);
复制代码

单例多例创建Bean都会调用到createBean

真正创建Bean是createBean()

//一般用于创建aop代理 
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//如果上边没有代理 这里会真正开始创建
Object beanInstance = doCreateBean(beanName, mbdToUse, args)
复制代码

createBean->resolveBeforeInstantiation

doCreateBean.1
doCreateBean.2
doCreateBean.3
走向如下面流程图 doCreateBean->createBeanInstance

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
bp instanceof MergedBeanDefinitionPostProcessor -> bp.postProcessMergedBeanDefinition(mbd, beanType, beanName)

populateBean

为刚刚实例化好的Bean进行属性等赋值

  • BeanWrapper为null直接报错或者return

  • InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
    官方的解释是:让用户可以自定义属性注入。比如用户实现一 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过 postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。当然,如果无 特殊需求,直接使用配置中的信息注入即可。另外,Spring 并不建议大家直接实现 InstantiationAwareBeanPostProcessor 接口,如果想实现这种类型的后置处理器,更建议 通过继承 InstantiationAwareBeanPostProcessorAdapter 抽象类实现自定义后置处理器

  • 这里会出现一个Spring的内部processor:AutowiredAnnotationBeanPostProcessor
    执行下去 进入postProcessProperties 首先找出所有的注解包括@Value @Autowired然后进行调用inject方法进行赋值
    最终是通过反射实现最终赋值
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);  
field.set(bean, value);
复制代码

applyPropertyValues(beanName, mbd, bw, pvs);
将属性应用到 bean 对象中

  • 检测属性值列表是否已转换过的,若转换过,则直接填充属性,无需再次转换

  • 遍历属性值列表 pvs,解析原始值 originalValue,得到解析值 resolvedValue

  • 对解析后的属性值 resolvedValue 进行类型转换

  • 将类型转换后的属性值设置到 PropertyValue 对象中,并将 PropertyValue 对象存入 deepCopy 集合中

  • 将 deepCopy 中的属性信息注入到 bean 对象中

流程图

exposedObject = initializeBean(beanName, exposedObject, mbd)

余下的初始化工作

invokeAwareMethods(beanName, bean)
若 bean 实现了 BeanNameAware、BeanFactoryAware、BeanClassLoaderAware 等接口,则向 bean 中注入相关对象
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
实例化前执行后置处理器对应的postProcessBeforeInitialization方法

invokeInitMethods(beanName, wrappedBean, mbd)

  1. 判断是否是InitializingBean的实现,执行接口规定的初始化afterPropertiesSet
  2. 执行invokeCustomInitMethod,方法大致是
    找出所有初始化方法(@Bean initMethod属性指定的方法) mbd.getInitMethodName() 对应去执行

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
执行 bean 初始化后置操作,AOP 会在此处向目标对象中织入切面逻辑

如果是FactoryBean

FactoryBean一直都没怎么用过 所以自己写了demo用下

    @Autowired
    private Student2 student2;
复制代码

debug一下 查看下执行过程

发现它是在Student2.Class是在 populateBean的时候调用processor进行inject时被实例化的,此时发现是FactoryBean就直接被调用了getObject 拿到这个bean 也就是说,一开始被实例化的只有MyFactoryBean这个类,而没有Student2这个类
MyFactoryBean此时 beanName=&myFactoryBean

总结

这次Spring ioc源码看了我好几天,收获还是挺大的,也总结

  1. 查看源码前提:是必须要知道怎么用
  2. 如果实在看不懂,可以google找再总结
  3. 有时有些很底层的可以先跳过,先直接到知道必将执行的方法打断点,由后往前看方法栈debug(如FactoryBean这部分)

最后关于Spring总结 主要按着下面四点去看 1)、Spring容器在启动,先保存Bean定义信息

  • xml注册bean
  • 注解注册Bean

2)、Spring容器会在XX的情况下创建Bean

  • 用到这个bean的时候 去创建 *finishBeanFactoryInitialization 统一创建bean

3)、后置处理器 *每一个Bean创建完成 会使用处理器处理

  • AutowiredAnnotationBeanPostProcessor 处理自动注入
  • XXXPostProcessor

4)、事件驱动模型 *ApplicationListener 事件监听 *ApplicationEventMulticaster 事件派发

转载于:https://juejin.im/post/5cb2cc775188251b0477e69b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值