bean创建过程与九次beanPostProcessor调用时机
2020-10-25 18:29:43 228 举报
Spring Bean的创建过程是一个复杂的过程,涉及到许多前置和后置处理器。在Spring容器中,当一个Bean被实例化时,会经过一系列的处理步骤。其中,九次beanPostProcessor调用是一个重要的环节。这些调用发生在Bean的初始化阶段,包括前处理、后处理等。通过这些调用,我们可以对Bean进行一些定制化的处理,例如修改属性值、添加日志记录等。总之,Spring Bean的创建过程是一个精心设计的流程,旨在为用户提供灵活、高效的开发体验。
作者其他创作
大纲/内容
获得方法参数
// 标记正在创建中beforeSingletonCreation(beanName)
DefaultListableBeanFactory#preInstantiateSingletons
AbstractAutowireCapableBeanFactory#createBean
获取自动装配模式,默认为NO
byName
初始化单例bean
singletonObject = this.earlySingletonObjects.get(beanName)
AbstractAutowireCapableBeanFactory#doCreateBean
Object sharedInstance = getSingleton(beanName)
注册一次性的bean
调用无参的构造方法实例化
DefaultSingletonBeanRegistry#getSingleton
处理自动装配,将依赖的属性装配到bean中
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName)
是正在创建从二级缓存池中获取
false
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd)
将获取早期对象的回调方法放到三级缓存中
applyBeanPostProcessorsAfterInitialization
先尝试从三级缓存中获取bean
初始化
Object singletonObject = this.singletonObjects.get(beanName)
调用回调方法获取早期bean
第二次调用bean后置处理器,只有AutowiredAnnotationBeanPostProcessor实现了处理逻辑
填充属性
调用createBean
清理状态
是否允许暴露早期对象
继续循环
invokeInitMethods
是否从缓存池中获取到了bean
bean是否正在创建是在创建bean的过程中进行的标记,该标记主要在发生循环依赖时使用
doCreateBean
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName)
实例化bean,这里将第二次调用后置处理器
afterSingletonCreation(beanName)
isFactoryBean(beanName)
AbstractAutowireCapableBeanFactory#createBeanInstance
getBean(beanName)
FACTORY_BEAN_PREFIX值为&,如果以&开头获取bean,返回的是一个工厂bean,并且不会调用getObject方法
依旧为空 && 允许早期引用从三级缓存中获取单例工厂
循环所有的beanName
singletonObject = singletonFactory.getObject()
applyMergedBeanDefinitionPostProcessors
refresh
!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()
autowireByType
调用set方法赋值如果不是xml byName byType 方式,其他方式pvs皆是空值
registerDisposableBeanIfNecessary
resolveDependency
ibp.postProcessProperties
......
将beanDefinition转化为RootBeanDefinition
转化beanName 如果是以&开头则去除,如果有别名则获取别名
true
调用初始化方法
获取不到,判断bean是否正在创建
找到了有参构造器
开始创建bean
第九次调用后置处理器,判断bean是否有销毁方法(取出第四次调用后置处理器时解析的@PreDestroy方法)有则将bean注册到销毁集合中,用于容器关闭时使用
实例化bean,并根据参数自动装配
mbd.getResolvedAutowireMode()
第四次,在getEarlyBeanReference中,使用beanPostProcessor对早期bean进行处理,如在AOP中生成代理对象
finishBeanFactoryInitialization
AbstractAutowireCapableBeanFactory#populateBean
// 如果有被@DependsOn标记,先创建DependsOn的beanString[] dependsOn = mbd.getDependsOn()
处理初始化后的bean
getBean(FACTORY_BEAN_PREFIX + beanName);
是否为工厂bean
实例化剩余的单例bean
不是抽象类并且是单例并且非懒加载
第三次,将标识了需要自动装配注解的属性或方法解析出来,包含的注解主要有 @Resource @Autowired @Value @Inject @PostConstruct @PreDestroy
applyBeanPostProcessorsBeforeInitialization
第六次,取出第四次调用beanPostProcessor解析出来的元数据,进行属性或方法装配,CommonAnnotationBeanPostProcessor 处理@Resouce注解的装配,AutowiredAnnotationBeanPostProcessor 处理@Autowired @Value @Inject注解的装配
autowireConstructor
第八次调用后置处理器,Spring内置后置处理器中,只有ApplicationListenerDetector有处理逻辑,ApplicationListenerDetector会将实现了ApplicationListener接口的bean添加到事件监听器列表中
处理beanDefinition的元数据信息
autowireByName
将早期对象放到二级缓存,移除三级缓存
如果bean实现了InitializingBean接口,则调用afterPropertiesSet方法,如果bean还实现了自定义的初始化方法,也进行调用,先afterPropertiesSet,再自定义
AbstractAutowireCapableBeanFactory#initializeBean
调用回调函数获取到bean
获得FactoryBean之后还会判断是否急需初始化,是则再次调用getBean(beanName)
singletonObject == null && isSingletonCurrentlyInCreation(beanName)
将创建好的bean返回
invokeAwareMethods
instantiateBean
AbstractApplicationContext#refresh
第七次调用后置处理器,ImportAwareBeanPostProcessor处理ImportAware接口,InitDestroyAnnotationBeanPostProcessor处理@PostContrust注解,ApplicationContextAwareProcessor处理一系列Aware接口的回调方法
第一次调用bean后置处理器,调用beanPostProcessor的applyBeanPostProcessorsBeforeInstantiation方法,在bean实例化之前的进行处理, Spring内置的后置处理器中,无相关实现,可使用自定义的后置处理器在这里进行中止bean的创建过程操作
在bean的初始化前进行处理
单例 && 允许循环依赖 && 正在创建中
sharedInstance != null
AbstractAutowireCapableBeanFactory#autowireByType
if(!ibp.postProcessAfterInstantiation) return;
beanFactory.preInstantiateSingletons()
if (bean != null) return bean;
从单例缓存池中获取
获取依赖的bean
进行创建bean
String beanName = transformedBeanName(name)
进行构造器推断,找到所有的有参构造器
byType
AbstractBeanFactory#getBean
0 条评论
回复 删除
下一页