Bean实例化过程和循环依赖
2023-03-01 18:45:15 1 举报
Bean实例化大流程
作者其他创作
大纲/内容
depends-on
getSingleton(beanName)
parseBeanDefinitionElement
4.最终把手机到的对象全部封装到LifecycleMetadata对象中,这个对象有一个list,有一个目标类
autowire-candidate
no
3.默认标签解析parseDefaultElement
postProcessBeforeInitialization
addSingletonFactories
4.解析bean中的lookup-method标签
@Servicepublic class CircularRefB { @Autowired private CircularRefA circularRefA;}
获取所有的BeanPostProcessor接口类型的对象,然后判断是否是SmartInstitationAwareBeanPostProcesser类型,然后循环调用determineCandiateConstructors方法,该方法的作用是获取有@Autowired注解的构造函数
id
2.parseBeanDefinitions
determineContructsFromBeanPostProcessors
getBean
3.调用实现了InitialzingBean接口的类中的afterPropertiesSet方法,调用init-method中配置的方法
createBean
populateBean
委托给Reader进行xml解析loadBeanDefinitions
postProcessMergedBeanDefinition
YES
earlySingletonObjects
singletonFactories
afterSingletonCreation(beanName)
AbstractBeanDefinitionReader
createBeanInstance
abstract
2.加载META-INF/spring.handlers配置文件,建立映射关系
1.doRegisterBeanfinitions
发射调用,把值设置到属性或者方法中
一级缓存:singletonObjects实例化完成之后往一级缓存中缓存实例,同时删除二级缓存,三级缓存
postProcessBeforeInitialzation
3.根据namespaceUri从映射关系中获取NamespaceHandler处理类
4.processBeanDefinition
CircularRefB circularRefB == null这时候堆内存的时候还没有依赖注入的,是一个光杆司令,已经有一个引用指向了这个对象
@Servicepublic class CircularRefA { @Autowired private CircularRefB circularRefB;}
跟AutowiredAnnotationBeanPostProcessor类的方法同样的逻辑
循环依赖流程
AbstractApplicationContext.obtainFreshBeanFactory
CommonAnnotationBeanPostProcessor
singletonObject=singleFactory.getObject()
5.调用NamespaceHandler的解析方法,开始真正的标签解析过程
1.构造函数有了,就是要获取到构造函数里面的参数值
loadBeanDefinitions(encodeResource)
是否配置了factory-method属性,或者是否有@Bean注解
AbstractRefreshableApplicationContext
触发属性的依赖注入操作
refreshBeanFactory()
DefaultListableBeanFactory
BeanDefinitionParserDelegate
调用匿名类中的creatBean方法,该方法会创建一个bean实例并返回
流程跟CommonAnnotationBeanPostProcessor类的postProcessMergedBeanDefinition方法的流程基本上是一模一样的,收集bean的属性和方法上面是否有@Autowired@Value注解,如果有则封装对象
1.创建GenericBeanDefinition对象
2.获取需要依赖注入的属性值,这里必定会出发beanFactory.getBean(beanName)
NO
无参构造函数的实例化,大部分情况会走这种方式的实例化,ctor.newInstance(args)
postProcessProperties
destroy-method
AbstractAutoProxyCreator
获取所有的BeanPostProcessor接口类型的对象,然后判断是否是MergedBeanDefinitionPostProcessor类型,然后循环调用postProcessMergedBeanDefinition方法,该方法的作用是对有@Authoried @Resource @PostConstruct @PreDestroy 注解的方法或者属性进行收集装配并封装成对象
circularRefA
4.返回有@Autowired注解的构造函数数组
ConstructorArgumentValues
判断正在实例化的bean是否有切面来判断到底当前bean是否需要生成代理,如果有切面,则生成代理,如果没有不生成代理
mbd.getFactoryMethodName !=null
XmlBeanDefinitionReader
创建BeanDefinitionDocumentReader对象,专门负责解析Document对象,委托模式
反射调用有@PostConstruct注解的方法,从metaData中拿到前面收集到的initMethods容器,到该容器里面就是收集到的有@PostConstruct注解的方法
这里是调到BeanPostProcessor接口,获取提前暴露的bean实例
2.调用@PostConstruct注解的方法,这里通过BeanPostProcessor接口实现该功能
CircularRefA的堆内存空间
AuthoredAnnotationBeanPostProcessor
AbstractAutowireCapableBeanFactory.doCreateBean()
autowire
这时候A的实例化还没有走完依赖注入
registerBeanDefinition完成对BeanDefinition对象的注册过程
1.支持@Lookup注解,扫描正在实例化的类中的方法,看看方法上面是否有@Lookup注解,如果有创建一个LookupOverride对象并添加到mbd.getMethodOverrides().addOverride(override)
字符串类型的xml文件路径,转换成Resource对象,包括模糊匹配
注册bean销毁时的类DisposableBeanAdapter
name
applyMergedBeanDefinitionPostProcessors
delegate.parseCustomElement自定义标签解析
initializeBean
1.调用Aware接口
class
BeanPostProcessor接口的循环调用
DefaultBeanDefinitionDocumentReader
4.调用NamespaceHandler的init初始化方法完成标签解析类的注册
1.postProcessMergedBeanDefinition根据该方法收集到的metaData数据,这个数据对象里面就封装了 有@Autowired注解的方法或者属性,有这个注解就表示这个方法或者属性需要依赖注入
创建XmlBeanDefinitionReader对象
determinedCandidateConstructors
返回BeanFactory
构造函数不为空
3.收集正在实例化的Bean方法中是否有@PreDestroy注解并把method对象封装成LifecycleElement对象
init-method属性,和InitialzingBean接口方法afterPropertiesSet调用 @PostConstruct注解方法调动,代理对象的生成入口
beforeSingletonCreation(beanName)
loadBeanDefinitions(beanFactory)
registerDisposableBeanIfNecessary
从Resource对象中后取文件流对象
primary
singletonObject对象缓存到二级缓存
getBeanFactory()
创建实例
getSingletonObjects
先从一级缓存中拿实例,如果有返回
从缓存中拿实例
7.解析bean中的property标签
factory-method
beanName singletonsCurrentlyInCreation容器删除
2.注册过程中DisposableBeanAdapter类中获取DestructionAwareBeanPostProcessor类型的接口,这个BeanPostProcessor接口专门用来销毁对象实例的
1.注册过程中DisposableBeanAdapter类中获取BeanDefinition对象中的destroy-method属性
2.解析bean标签的属性,并把解析出来的属性设置到BeanDefinition对象中
AbstractXmlApplicationContext
doLoadBeanDefinitions
bean注入singletonsCurrentlyInCreation容器
MethodOverrides
一级缓存中没有,从二级缓存中拿,如果有返回
构造函数为空
parent
instantiateBean
2.获取bean对应的所有构造器,rawCandidates = beanClass.getDeclaredConstructors();
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&\t\t\t\tisSingletonCurrentlyInCreation(beanName))
lazy-init
init-method
font color=\"#ff3333\
根据InputSource JDK的SAX解析,生成Document对象,doLoadDocument
autowireConstructor
4.代理实例创建,用BeanPostProcessor接口来完成代理实例的生成
5.解析bean中的replaced-method标签
instantiateUsingFactoryMethod
addSingletoFactory
从缓存中获取不到实例
6.解析bean中的constructor-arg标签
设置三级缓存,往singletonFactory存储了ObjectFactory对象,在getObject方法中getEarlyBeanReference方法调用
AutowiredAnnotationBeanPostProcessor
postProcessAfterInitialization
2.收集正在实例化的Bean方法中是否有@PostConstruct注解并把method对象封装成LifecycleElement对象
如果二级缓存中没有且allowEarlyReference=true允许提前暴露,从三级缓存中拿,拿到的是一个ObjectFactory对象
2.registerBeanDefinitions
1.获取标签的namespaceUri
GenericBeanDefinition
ObjectFacotry.getObject()
3.获取到构造函数上的@Autowired注解信息,AnnotationArrtributes ann = findAutowiredAnnotation(candidate);AnnotationAttributes是一个map对象
MutablePropertyValues
yes
反射调用factory-method方法,该方法会返回一个自定义创建的实例,然后返回,后面的实例化就不走了
把流对象冯庄村InputSource对象,JDK自带的sax解析对象
dependency-check
1.构造函数中注册了@PostConstruct和@PreDestroy注解
determineCadidateConstructors
3.解析bean中的meta标签
收藏
收藏
0 条评论
下一页