Spring之bean的生命周期

在上一篇文章中已经对Spring扫描流程进行了解析,这一篇spring之bean的生命周期就接着上一篇继续讲。
https://blog.csdn.net/u014518603/article/details/135333272

bean的生命周期流程

  1. 生成beanDefinition:通过上一篇扫描得到
  2. 合并beanDefinition
  3. 加载类
  4. 实例化前:若在此返回一个bean,则直接跳到初始化后aop步骤
  5. 实例化
  6. BeanPostProcessor后置处理器
  7. 实例化后
  8. 属性填充:自动注入autowireMode
  9. 属性填充:@Autowired @Resource
  10. 执行aware回调
  11. 初始化前 :包括@PostConstruct
  12. 初始化: InitializingBean.afterPropertiesSet() , init-method
  13. 初始化后

合并父子BeanDefinition

spring启动扫描完成后,得到了beanDefinitionMap,接着调用AbstractApplicationContext.refresh()中的finishBeanFactoryInitialization()方法,最终调用的是beanFactory.preInstantiateSingletons();实例化所有非懒加载的单例bean。此处的beanFactory具体是DefaultListableBeanFactory
在这里插入图片描述
在这里插入图片描述
进入beanFactory.preInstantiateSingletons();方法后,下一步调用getMergedLocalBeanDefinition()方法合并父子beanDefinition,得到RootBeanDefinition

在这里插入图片描述

创建factoryBean

如果当前beanDefinition是factoryBean,则将&beanName传参给getBean()方法获取bean。

在这里插入图片描述
getBean()会调用doGetBean()方法。先截取&,然后从单例池获取bean。获取到bean后再调用方法getObjectFromBeanInstance()判断是否是factoryBean
在这里插入图片描述

如果getObjectFromBeanInstance()判断当前bean是factoryBean,
则调用getCachedObjectForFactoryBean()方法先从factoryBeanObjectCache缓存中获取。
在这里插入图片描述

缓存中不存在则调用getObjectFromFactoryBean(),最终是调用factoryBean的getObject()方法生成bean,并放入缓存factoryBeanObjectCache
在这里插入图片描述

创建普通单例bean

如果当前beanDefinition不是factoryBean,则进入DefaultListableBeanFactory.getBean()方法开始创建bean,调用doGetBean(),获取父beanFactory,从当前beanFactory获取不到beanDefinition,则从父beanFactory获取。
在这里插入图片描述

接下来开始合并父子beanDefinition,调用getMergedLocalBeanDefinition()生成的新RootBeanDefinition,checkMergedBeanDefinition()检查RootBeanDefinition是抽象的,则抛异常,因为抽象beanDefinition不能生成bean。

然后获取beanName对应的dependsOn依赖类,存入数组dependsOn

遍历数组dependsOn,如果出现两个类互相依赖,则抛异常。

将@DependsOn(“xxx”)中的xxx存到dependentBeanMap中,表示某个bean,被哪些bean依赖了。然后通过getBean()获取依赖的bean。
在这里插入图片描述

判断作用域
  1. 当前beanDefinition的作用域是单例的,先从单例池获取,找不到再调用createBean();
    在这里插入图片描述
  2. 当前beanDefinition的作用域是原型的,则直接调用createBean()创建新的实例。

在这里插入图片描述

进入createBean()主流程

加载class对象

首先加载class对象resolveBeanClass()根据beanName从beanDefinition的beanClass属性获取到Object类型的字符串"com.xx.Student"。然后克隆出一个RootBeanDefinition,将获取到的class对象设置到beanClass属性中。
在这里插入图片描述

实例化前

resolveBeforeInstantiation(),如果在这一步就返回一个bean,那么后面就直接跳到初始化后的步骤进行aop操作了。
在这里插入图片描述
执行接口InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法
在这里插入图片描述
在这里插入图片描述

@Component
public class WjBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		if ("student".equals(beanName)) {
			System.out.println("实例化前");
			// 如果在这里return一个实例化的对象,则后面的步骤不会再执行,直接直接初始化后的操作
		}
		return null;
	}
}
实例化

doCreateBean()会调用createBeanInstance()创建bean对象,通过推断构造方法,或者通过自动注入模型的autowireMode = byConstructor
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实例化后

执行接口InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法
在这里插入图片描述

属性填充
通过自动注入模型autowireMode填充属性

populateBean() 通过beanDefinition的autowireMode字段属性进行自动注入。通过xml配置aotuwire=“byName”、"byType"来设置自动注入的模式。
:这种方式现在已经不推荐使用了,因为它的控制粒度不够细类中的所有set方法都会被当做注入点。而@Autowired可以加在属性、方法、构造方法上,可以由开发人员控制在哪里进行注入。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
通过byName、byType两种方式注入需要在类中提供set方法。
byName:通过解析setXXX() 拿到XXX作为beanName去容器中获取bean,找不到则报错,XXX必须与beanName一致。

在这里插入图片描述
byType:通过setXXX( YYY yyy); 拿到属性类型,并根据类型去容器中找bean,找不到则报错。

通过解析注解@Autowired、@Resource填充属性

获取所有实现了接口InstantiationAwareBeanPostProcessor.postProcessProperties()方法的beanPostProcessor,遍历它们。其中两个重要类是AutowiredAnnotationBeanPostProcessor用于解析@Autowired注解,
CommonAnnotationBeanPostProcessor用于解析@Resource注解。
在这里插入图片描述
找到注入点集合,封装到对象InjectionMetadata中,然后遍历注入点集合,通过反射给bean注入属性。
在这里插入图片描述
在这里插入图片描述

初始化

initializeBean()
在这里插入图片描述

aware回调

invokeAwareMethods()

在这里插入图片描述

初始化前

applyBeanPostProcessorsBeforeInitialization() 执行所有实现了接口BeanPostProcessor.postProcessBeforeInitialization()方法。这一步包含了@PostConstruct方法的执行
在这里插入图片描述

初始化

invokeInitMethods()执行接口InitializingBean.afterPropertiesSet()方法
在这里插入图片描述
invokeInitMethods()执行从RootBeanDefinition的属性initMethod获取到的初始化方法,可以通过beanDefinition指定initMethod,或者通过xml给bean配置一个属性init-method来指定初始化的方法。
在这里插入图片描述

初始化后

applyBeanPostProcessorsAfterInitialization() 执行所有实现了接口BeanPostProcessor.postProcessAfterInitialization()方法
在这里插入图片描述

处理循环依赖
在这里插入图片描述
定义bean的销毁逻辑
在这里插入图片描述

最后,
DefaultListableBeanFactory.preInstantiateSingletons()方法在创建完成所有的非懒加载的单例bean后,会再次遍历单例池中的bean,判断是否实现了接口SmartInitializingSingleton,然后执行它的方法afterSingletonsInstantiated()
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值