微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

spring --bean的生命周期

bean生命周期 概述

protected <T> T doGetBean(
            String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)

bean的生命周期从调用beanfactory的doGetBean开始,到这个bean被销毁,可以总结为以下七个阶段

@H_404_8@
  • 处理名称,检查缓存
  • 处理父子容器
  • 处理dependsOn
  • 选择Scope策略
  • 创建bean
  • 类型转换处理
  • 销毁bean
  • 1.处理名称,检查缓存

    • 这一步会处理别名,将别名解析为实际名称

    • factorybean 也会特殊处理,如果以 & 开头表示要获取 factorybean 本身,否则表示要获取其产品

    • 这里针对单例对象会检查一级、二级、三级缓存

      • singletonFactories 三级缓存,存放单例工厂对象

      • earlySingletonObjects 二级缓存,存放单例工厂的产品对象

        • 如果发生循环依赖,产品是代理;无循环依赖,产品是原始对象

      • singletonObjects 一级缓存,存放单例成品对象

    2. 处理父子容器

    • 如果当前容器根据名字找不到这个 bean,此时若父容器存在,则执行父容器的 getBean 流程

    • 父子容器的 bean 名称可以重复

    3. 处理 dependsOn

    • 如果当前 bean 有通过 dependsOn 指定了非显式依赖的 bean,这一步会提前创建这些 dependsOn 的 bean

    • 所谓非显式依赖,就是指两个 bean 之间不存在直接依赖关系,但需要控制它们的创建先后顺序

    4. 选择 scope 策略

    • 对于 singleton scope,首先到单例池去获取 bean,如果有则直接返回,没有再进入创建流程

    • 对于 prototype scope,每次都会进入创建流程

    • 对于自定义 scope,例如 request,首先到 request 域获取 bean,如果有则直接返回,没有再进入创建流程

    5.1 创建 bean - 创建 bean 实例

    要点总结
    自定义 TargetSource 的情况 由 AnnotationAwareAspectJAutoproxyCreator 创建代理返回
    supplier 方式创建 bean 实例 为 Spring 5.0 新增功能,方便编程方式创建 bean 实例
    FactoryMethod 方式 创建 bean 实例 ① 分成静态工厂与实例工厂;② 工厂方法若有参数,需要对工厂方法参数进行解析,利用 resolveDependency;③ 如果有多个工厂方法候选者,还要进一步按权重筛选
    AutowiredAnnotationBeanPostProcessor ① 优先选择带 @Autowired 注解的构造;② 若有唯一的带参构造,也会入选
    mbd.getPreferredConstructors 选择所有公共构造,这些构造之间按权重筛选
    采用认构造 如果上面的后处理器和 BeanDefiniation 都没找到构造,采用认构造,即使是私有的
     

    5.2 创建 bean - 依赖注入

    要点总结
    AutowiredAnnotationBeanPostProcessor 识别 @Autowired 及 @Value 标注的成员,封装为 InjectionMetadata 进行依赖注入
    CommonAnnotationBeanPostProcessor 识别 @Resource 标注的成员,封装为 InjectionMetadata 进行依赖注入
    resolveDependency 用来查找要装配的值,可以识别:① Optional;② ObjectFactory 及 ObjectProvider;③ @Lazy 注解;④ @Value 注解(${ }, #{ }, 类型转换);⑤ 集合类型(Collection,Map,数组等);⑥ 泛型和 @Qualifier(用来区分类型歧义);⑦ primary 及名字匹配(用来区分类型歧义)
    AUTOWIRE_BY_NAME 根据成员名字找 bean 对象,修改 mbd 的 propertyValues,不会考虑简单类型的成员
    AUTOWIRE_BY_TYPE 根据成员类型执行 resolveDependency 找到依赖注入的值,修改 mbd 的 propertyValues
    applyPropertyValues 根据 mbd 的 propertyValues 进行依赖注入(即xml中 <property name ref|value/>

    5.3 创建 bean - 初始化

    要点总结
    内置 Aware 接口的装配 包括 BeanNameAware,beanfactoryAware 等
    扩展 Aware 接口的装配 由 ApplicationContextAwareProcessor 解析,执行时机在 postProcessBeforeInitialization
    @postconstruct 由 CommonAnnotationBeanPostProcessor 解析,执行时机在 postProcessBeforeInitialization
    InitializingBean 通过接口回调执行初始化
    initMethod 根据 BeanDeFinition 得到的初始化方法执行初始化,即 <bean init-method> 或 @Bean(initMethod)
    创建 aop 代理 由 AnnotationAwareAspectJAutoproxyCreator 创建,执行时机在 postProcessAfterInitialization

    5.4 创建 bean - 注册可销毁 bean

    在这一步判断并登记可销毁 bean

    • 判断依据

      • 如果实现了 disposableBean 或 AutoCloseable 接口,则为可销毁 bean

      • 如果自定义了 destroyMethod,则为可销毁 bean

      • 如果采用 @Bean 没有指定 destroyMethod,则采用自动推断方式获取销毁方法名(close,shutdown)

      • 如果有 @PreDestroy 标注的方法

    • 存储位置

    • 存储时都会封装为 disposableBeanAdapter 类型对销毁方法调用进行适配

    6. 类型转换处理

    • 如果 getBean 的 requiredType 参数与实际得到的对象类型不同,会尝试进行类型转换

    7. 销毁 bean

    • 销毁时机

      • singleton bean 的销毁在 ApplicationContext.close 时,此时会找到所有 disposableBean 的名字,逐一销毁

      • 自定义 scope bean 的销毁在作用域对象生命周期结束时

      • prototype bean 的销毁可以通过自己手动调用 AutowireCapablebeanfactory.destroyBean 方法执行销毁

    • 同一 bean 中不同形式销毁方法调用次序

      • 优先后处理器销毁,即 @PreDestroy

      • 其次 disposableBean 接口销毁

      • 最后 destroyMethod 销毁(包括自定义名称,推断名称,AutoCloseable 接口 多选一)

     

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

    相关推荐