分析Spring中Bean的生命周期

本文详细剖析了Spring中Bean的生命周期,从实例化、依赖注入到Aware接口、BeanPostProcessor处理,再到InitializingBean和init-method,最后是DisposableBean和destroy-method。文中通过实例代码展示了Bean从创建到销毁的全过程。
摘要由CSDN通过智能技术生成
写在最前

从十一到现在两周,IOC部分源码读了一半多,是力气活,也是个精细活。全部写出来心有余力不足,所以找些重点写写。

简述 bean 实例化之前

Spring中不是启动容器时就开启bean的实例化进程,它首先会对资源进行读取并对bean进行初始化。

Spring将资源的定义和资源的加载区分开,Resource定义了统一的资源,默认实现是AbstractResource,资源的加载由ResourceLoader接口的不同实现类返回Resource。紧接着,解析Resource资源,将用户定义的Bean装载成BeanDefinition,每一个Bean对象都对应着一个BeanDefinitionBeanDefinition存在于IOC内部容器中的HashMap结构。再紧跟着,向IOC容器注册解析好的BeanDefinition,这个过程是通过BeanDefinitionRegistry接口来实现的。

初始化之后,会进行真正bean的加载,因为BeanDefinition不是想要的bean。初始化默认为懒加载,第一次调用getBean()时进行初始化。

首先得到可使用正确的beanName,这是涉及到别名或者factoryBean 。bean的作用域有singleton,prototype 和其他,Spring先尝试从缓存中加载单例bean,否则开始创建bean的实例。创建bean的实例可以理解为将BeanDefinition转换为BeanWrapper,BeanWarpper提供了get、set方法。之后还有一系列处理:MergedBeanDefinitionPostProcessor 属性合并,单例模式的循环依赖处理,属性填充,初始化bean。

在初始化bean这个过程中的代码,就包含了对XXXAware接口的处理,后置处理器,以及自定义的init-method方法。

Bean生命周期

回到最开始,看一下spring bean 的生命周期:

img

  1. 实例化Bean

    对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。

    对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean。

    容器通过获取BeanDefination对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入。

    实例化对象被包装在BeanWrapper对象中,BeanWrapper提供了设置对象属性的接口,从而避免了使用反射机制设置属性。

    在实例化bean的过程中,Spring采用策略模式决定采用反射还是 CGLIB 动态字节码。Spring 默认采用 CglibSubclassingInstantiationStrategy实例化bean,他既可以以反射实例化对象,还可以通过 CGLIB 的动态字节码的方式,以方法(setXxx)的方式注入对象实例化。

  2. 设置对象属性(依赖注入)

    实例化后的对象被封装在BeanWrapper对象中,并且此时对象仍然是一个原生的状态,并没有进行依赖注入。

    紧接着,Spring根据BeanDefinition中的信息进行依赖注入。

    并且通过BeanWrapper提供的设置属性的接口完成依赖注入。

  3. 注入Aware接口

    紧接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean。

    private void invokeAwareMethods(final String beanName, final Object bean) {
         
        if (bean instanceof Aware) {
         
            if (bean instanceof BeanNameAware) {
         
                ((BeanNameAware) bean).setBeanName(beanName);
            }
            if (bean instanceof BeanClassLoaderAware) {
         
                ClassLoader bcl = getBeanClassLoader();
                if (bcl != null) {
         
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                }
            }
            if (bean instanceof BeanFactoryAware) {
         
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值