• Spring之Bean的生命周期


     一.Bean的生命周期:

    1. 实例化 Instantiation: Bean的创建
    2. 属性赋值 Populate  
    3. 初始化 Initialization: 把bean相关的BeanName,BeanClassLoader,如有自定义初始化方法则调用
    4. 使用Bean:可以通过IOC容器使用Bean
    5. 销毁:从Map中移除该Bean,调用Bean的销毁方法

     实例化 -> 属性赋值 -> 初始化 -> 销毁

    主要逻辑都在doCreate()方法中,逻辑很清晰,就是顺序调用以下三个方法,这三个方法与三个生命周期阶段一一对应,非常重要,在后续扩展接口分析中也会涉及。

    1. createBeanInstance() -> 实例化
    2. populateBean() -> 属性赋值
    3. initializeBean() -> 初始化

    源码如下,只列了关键代码,便于理解:

    //AbstractAutowireCapableBeanFactory
    protected
    Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //1 创建bean 实例化阶段 =创建一个bean 对象 instanceWrapper = this.createBeanInstance(beanName, mbd, args); } Object exposedObject = bean; try { //2 属性赋值阶段 this.populateBean(beanName, mbd, instanceWrapper); //3 初始化阶段 exposedObject = this.initializeBean(beanName, exposedObject, mbd); } catch (Throwable var18) { if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) { throw (BeanCreationException)var18; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18); } }

    至于销毁,是在容器关闭时调用的,先销毁Bean,再销毁容器,详见ConfigurableApplicationContext#close()

     1  protected void doClose() {
     2         if (this.active.get() && this.closed.compareAndSet(false, true)) {
     3             if (this.logger.isInfoEnabled()) {
     4                 this.logger.info("Closing " + this);
     5             }
     6 
     7             LiveBeansView.unregisterApplicationContext(this);
     8 
     9             try {
    10                 this.publishEvent((ApplicationEvent)(new ContextClosedEvent(this)));
    11             } catch (Throwable var3) {
    12                 this.logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", var3);
    13             }
    14 
    15             if (this.lifecycleProcessor != null) {
    16                 try {
    17                     this.lifecycleProcessor.onClose();
    18                 } catch (Throwable var2) {
    19                     this.logger.warn("Exception thrown from LifecycleProcessor on context close", var2);
    20                 }
    21             }
    22             //将bean 从map中remove掉
    23             this.destroyBeans();
            //DefaultListableBeanFactory ,将bean置为null
    24 this.closeBeanFactory(); 25 this.onClose(); 26 this.active.set(false); 27 } 28 29 }

    二.常用接口

    • BeanPostProcessor
    • InstantiationAwareBeanPostProcessor
    • InitializingBean 
     

    三.执行顺序

    BeanPostProcessor有很多个,而且每个BeanPostProcessor都影响多个Bean,其执行顺序至关重要,必须能够控制其执行顺序才行。关于执行顺序这里需要引入两个排序相关的接口:PriorityOrdered、Ordered

    • PriorityOrdered首先被执行,PriorityOrdered之间通过接口返回值排序

    • Ordered然后执行,Ordered之间通过接口返回值排序

    • 都没有实现是最后执行

    根据排序接口返回值排序,默认升序排序,返回值越低优先级越高。

  • 相关阅读:
    一个思绪凌乱的前端
    如何将你的github仓库部署到github pages(github.io博客)
    聊一聊前端系列篇
    Centos7升级gcc极简教程
    Pycharm报错连接linux服务器报错:Could not verify `ssh-rsa` host key with fingerprint
    基于Pytorch的简单小案例
    windows安装Pytorch报错:from torch._C import * ImportError: DLL load failed: 找不到指定的模块”解决方案
    scrapy抓取豆瓣电影相关数据
    scrapy结合selenium抓取武汉市环保局空气质量日报
    scrapy抓取国家社科基金项目数据库
  • 原文地址:https://www.cnblogs.com/fanBlog/p/12626923.html
Copyright © 2020-2023  润新知