着重观察refresh方法
前面七个方法是做一些准备工作,第八个方法是真正的spring创建bean开始。本文只介绍关键步骤
1.第一个方法
一个模板方法 允许子类实现beanfactory后置处理
2.第二个方法
调用beanfactory处理器
3.第三个方法
注册bean的后置处理器beanpostprocessor
4.第四个方法
初始化消息源
5.第五个方法
初始化应用实际事件发布的委托
6.第六个方法
一个模板方法 子类实现 可定义特定的刷新方法
7.第七个方法
查询监听器 并注册
8.第八个方法(重点)
实例化所有非懒加载单利bean
8.1进入方法
红框之前是准备操作,红款真正开始创建bean 此处流程为创建第一个对象A
此处循环遍历所有的beanDefinition(里面记录了bean的基本信息是否懒加载是否单例等),先判断是否是factoryBean对象,如果不是就走创建bean方法,也就是红框,进入是重载方法
再次进入到实际执行方法,先尝试获取bean
getsingleton方法实现如下
首先从一级缓存singletonObjects中获取bean对象,如果没有则到二级缓存earlySingletonObjects获取对象,如果还是没有,则到三级缓存singletonFactories中查找,如果三级缓存存在,则清除三级缓存中的ObjectFactory对象,通过三级缓存查询的对象调用getObject方法生成的不完全的bean对象放入二级缓存。概念:一级缓存:执行完bean生命周期完整的bean对象。二级缓存:只执行了一部分beanpostprocessor的不完整的bean对象。三级缓存:bean对应的ObjectFactory是一个工厂对象。
此处会判断对象是否存在,如果存在则走getObjectForBeanInstance方法,此处第一次不存在,本方法下面再介绍。
首先判断是否创建过,之后如果查不到beandefinition信息则到父类beanfactory获取
实例化bean对象,此处传入参数beanName以及一个lambda表达式
进入getSingleton,此处又是getSingleton一个重载方法
通过刚刚的lambda表达式调用getObject获取singletonObject
lambda表达式调用了createbean方法,进入creatbean方法
这边是判断是否需要生成代理对象而不是原对象,分为实例化之前和初始化之后。先看实例化之前。
判断对象所有的beanpostprocessor,如果有实现了InstantiationAwareBeanPostProcessor接口的则执行生成代理操作,如果有实例化之前则会走初始化之后
初始化之后就是遍历执行bean后置处理器
这边是设置bean是否做过实例化之前增强,如果这一步bean!=null则creatBean流程结束,如果为null则继续
不需要实例化之前增强则会走正常的创建bean流程,进入
首先从factoryBeanInstance获取bean获取不到则实例化对象
实例化之后 执行合并beandefinition类型的处理器,看一下此处理器的实现
可以看到其中有autowired、定时任务、required等注解处理就在这一步
此处判断是否是单例、是否允许循环依赖、是否是正在创建的对象
如果满足上述条件则会进入这个方法,同样的会传入一个beanName以及一个lambda表达式对应的是ObjectFactory对象
此处是将完成实例化的对象放入三级缓存,并清理二级缓存,并将beanName放入标记已注册set集合中,注意这里是实例化之后将自己暴露在三级缓存,所以如果是构造器注入则无法解决循环依赖。
首先进入populateBean方法,此方法为填充属性的值
进入方法后会先执行实例化处理器的后置处理器操作也就是postProcessAfterInstantiation方法
1.判断是否注册instantiation处理器并执行;2.是否需要依赖检查,如果需要检查则会判断对应的类型是否被设置。
执行准备填充属性
返回一个传入属性的对象
此处可以看到再次调用了getBean方法,进入
再次进入doGetBean方法,开始创建对象B
和创建A一样先从三级缓存中查询是否存在对象,后续流程和创建A一样,此处关注属性赋值
此处也是走的doGetBean
此处第三级缓存中存有a的ObjectFactory对象
此处会走之前传入的lambda表达式
此处主要是执行实现了smartInstantiationAwareBeanPostProcessor接口的处理器的方法,其中AbstractAutoProxyCreator类实现了此接口。主要是为了处理aop,这一步之后会讲代理对象放入二级缓存,并且删除三级缓存中的对象。
此处将a放入了早期代理引用(早期代理引用指的是循环依赖中只执行了aop处理的不完整的bean)的set集合中,为了之后执行后置处理器不重复执行proxy。
补充:此方法是bean初始化后置处理器执行的aop增强的方法,这里会先到早期引用代理判断对象是否存在如果存在则不需要再做aop处理。
此处为AbstractAutoProxyCreator实现接口之后的具体实现方法,主要就是获取所有的增强,并添加到标记是否需要增强的map中 设置为false(不需要)
此处执行动态代理,cglib或者jdk并返回。然后属性赋值,完成b的创建(完整的bean),创建完成后会将二级三级缓存中的b清理,并放入一级缓存中。
回到A对象创建,分析一下属性赋值之后初始化的工作内容,进入方法
可以清楚地看到初始化流程会先执行beanPostBeforeInitialiaztion然后执行invokeInitMethods最后执行beanPostAfterInitialiaztion
其中invokeInitMethods方法中会先执行afterPropertiesSet然后才是initmethod。(@PostConstruct注解方法优于这两个方法)
如果是标记循环依赖的对象则到二级或三级缓存获取对象,并返回,此时完成docreatbean方法。最后将完整的a的bean对象放入一级缓存并清空二级三级缓存。
2021-1-28----补充
补充一下@autowired装配。之前说到了mergedBeanDefinition类,这边会将需要autowired等注解进行记录
在执行applyPropertyValues方法之前会先判断是否有实例化处理器以及是否需要自动注入,如果需要就会走如图判断,遍历所有处理器,并执行符合要求的
可以看出autowired注解处理器是InstantiationAwareBeanPostProcessor的子类,会走其中的逻辑。
首先获取到所有autowired的元数据,然后进行注入。
找出全部的element并逐个注入(如何解析出element的接下来讲)
这边先查缓存,然后获取被依赖对象以及依赖对象以及类型,然后通过beanFactory的resolveDependency方法获取值
首先判断是不是必须的,是不是objectfactory,然后这边主要看最后一个else的内容,获取懒加载对象,如果没有则走doResolveDependency方法。
这个方法中其他的也是一些判断和获取信息,主要看这行代码,就是加载所需要的类
到这里就可以看到熟悉的beanfactory.getBean方法了,然后就是走创建bean的流程了
如果我没猜错,等我在看几次,后续这个文章应该会有补充以及修改!