getBean流程(新)(又名:Spring 依赖注入(DI) 源码解析时序图)
2021-04-06 11:59:33 1 举报
getBean流程(新)(又名:Spring 依赖注入(DI) 源码解析时序图)
作者其他创作
大纲/内容
③
autowireByName()方法
调用自定义Bean中重写的afterPropertiesSet()方法
第1步:调用createBeanInstance()方法,开始创建Bean实例的早期对象
①判断当前bean有无实现InstantiationAwareBeanPostProcessors接口
解析所有的属性值是否都在当前bean的配置文件中
AbstractPropertyAccessor
调用getSingleton()获取bean实例重点:此处重写了getObject()方法
autowireConstructor()方法
调用registerDependentBean() span style=\"font-size: inherit;\
③其他
创建bean实例代码附上
getObject()方法
各类型开始判断
BY_NAME
备注:
检查单例缓存池中是否有Bean对象
Yes
调用方法autowireByType()
使用JDK的反射机制创建对象
扩展点介绍:InstantiationAwareBeanPostProcessors 一种后置处理,用于在 Spring 填充属性到 bean 对象前,对属性的值进行相应的处理,比如可以修改某些属性的值。这时注入到 bean 中的值就不是配置文件中的内容了, 而是经过后置处理器修改后的内容。具体用法:参考:https://blog.csdn.net/qq_38526573/article/details/88091702
就是因为在初次创建完bean对象后,通过addSingleton()方法将其添加到了Spring缓存中,所以再次getBean()就可以直接获取到bean对象了
当Spring工程启动完毕,再通过getBean()方式获取Bean对象,此时单例缓存池已经有Bean对象,所以直接返回即可(如上图图2方式)
第3步:早期对象创建完成,开始对创建的bean进行属性赋值
判断
xml方式:(即配置了factory-method方式创建) 1.使用静态工厂方式实例化Bean 2.使用实例工厂方法实例化Bean(参考:https://blog.csdn.net/lzb348110175/article/details/115134145)注解方式: 1.以我们常用的@Bean方式最多(在配置文件中是我们使用的@Bean的形式都是通过工厂方法的形式来实例化对象) @Bean public Person person() { return new Person(); }
autowireByType()方法
populateBean()方法
检查当前Bean有无继承关系
registerDependentBean()方法
AbstractBeanFactory
addSingletonFactory()方法
BY_TYPE
②是BeanDefinitionHolder类型
(为创建的bean进行属性赋值操作)
Address属性没有在person中配置,通过getBean()获取bean实例
①有解析到工厂方法, 即:1.xml配置中使用了的factory-method来创建 2.注解配置,即使用@Bean方式最多
调用 setPropertyValue()方法,开始设置属性值
①
②别名方式获取beanName。(如果传入的是别名,则通过该方法,使用do{}while(...)方式去掉前缀来获取实际的beanName)
getBean()方法
调用 doGetBean()方法,工作干活
②原型模式
调用getSingleton()方法,获取单例bean对象
判断当前bean的作用域是否为单例
①回调我们是否有重写了xxxAware接口的类,有的话,就开始进行回调重写后的方法
调用transformedBeanName() 方法,获取beanName
②通过getPropertyValues()方法,获取当前bean实例配置的属性值
doGetBean()方法
如有必要,提前暴露早期对象,即添加到Spring三级缓存中
创建bean对象分如下3种情况考虑
调用instantiate()方法,实例化Bean对象
createBean()方法
......
②调用所有bean的后置处理器的before前置方法
③调用invokeInitMethods()方法
setPropertyValues()方法
重写后的方法如图:
何为早期对象:对象创建出来了,但是还没有进行赋值的对象。
setPropertyValue()方法
③啥都没有,则使用无参构造方法
mbd.getResolvedAutowireMode()方法
④调用applyPropertyValues()方法,将属性设置到beanWrapper中
通过反射,调用bean实例的setXXX()方法进行属性赋值
①FactoryBean方式创建。(通过FactoryBean方式创建的有&前缀,通过使用do{}while(...)方式去掉前缀来获取实际beanName)
①如果有构造方法
getBean() 流程
AbstractNestablePropertyAccessor
②
④调用所有bean的后置处理器的after后置方法
此处解决bean的循环依赖引用问题
BeanUtils.getWriteMethodParameter(pd)方法
resolveBeforeInstantiation()方法
⑤
instantiateUsingFactoryMethod()方法
该过程比较复杂,此处不做研究
方法返回后,调用重写过的getObject()方法
No
判断是否需要暴露代码
接上文开始分析:https://www.processon.com/view/link/604f20ebe401fd11ed162e1d
此方法是干什么的?
hasInstantiationAwareBeanPostProcessors()方法
获取beanName
②根据beanClass和beanName,去bean的后置处理器中获取构造方法
instantiateBean()方法
此处用于解决bean循环依赖问题
调用
初次启动Spring项目,单例缓存池为空,肯定是没有创建好的Bean对象的
resolveValueIfNecessary()方法
getSingleton(beanName)方法
常见的调用getBean()方式:1.源代码中对自定义扩展点进行getBean()调用(图1)2.自己学习时,通过getBean()方式获取bean对象(图2)
instantiate()方法
调用resolveDependency()方法,解析依赖关系
⑤是List、Set、Map等各类型判断
使用CgLib代理创建对象
没有
②并且有使用@Autowired自动装配方式标注
setValue()方法
④是Array类型
addSingleton()方法
最终:返回bean实例对象
第2步:判断是否需要提前暴露早期对象(用于解决bean循环依赖)
调用方法autowireByName()
开始创建bean实例
调用setValue()方法
AbstractApplicationContext
此方法,是给BeanPostProcessors一个返回代理而不是目标bean实例的机会实际:在Spring IOC容器初始化时,根本不会创建代理。目前还只是BeanDefinition,根本没有bean对象,代理个锤子啊方法存在的意义:该方法在Spring AOP中是一个重要方法。在此处,该方法会提前把切面/切点找出来,提前进行缓存,然后再去代理目标对象,切面已经找到,直接从缓存中获取,直接织入AOP即可
③通过getResolvedAutowireMode()方法,解析bean实例注入的类型,获取属性之间的依赖关系
检查我们自定义的Bean是否实现InitializingBean接口,实现的话,则回调重写的afterPropertiesSet()方法
2.调用SetXXX方法设置属性
initializeBean()方法
有
一共是有如下3种Aware接口:①BeanNameAware②BeanClassLoaderAware③BeanFactoryAware
resolveDependency()方法
createBeanInstance()方法
SimpleInstantiationStrategy
1.解析出属性值
mbd.getPropertyValues()方法
beforeSingletonCreation(beanName)方法
属性值类型判断
doCreateBean()方法
调用BeanUtils.getWriteMethodParameter(pd)方法,获取setter方法(write method)的参数信息。比如:参数在参数列表中的位置、参数类型、以及该参数所归属的方法等信息
AbstractAutowireCapableBeanFactory
将当前beanName添加至Set集合(当前正在创建的单例)
DefaultSingletonBeanRegistry
包括如下两种方式
①单例模式
③是BeanDefinition类型
调用createBean()方法
④
①判断解析的值是不是 运行时bean的引用
经①②③三步创建bean完成后,getSingleton()方法最终调用addSingleton()方法,将创建完成的bean对象添加至缓存中,供后续getBean()获取对象时,可以直接获取到,省去再次创建bean的性能消耗
0 条评论
回复 删除
下一页