zoukankan      html  css  js  c++  java
  • 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之间通过接口返回值排序

    • 都没有实现是最后执行

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

  • 相关阅读:
    Maven 在pom.xml的build中配置resources,来防止我们资源导出失败的问题
    JavaWeb
    MySQL
    JavaScript
    Caused by: org.apache.ibatis.exceptions.PersistenceExceptiong 更新IDEA后报错
    Loading class `com.mysql.jdbc.Driver‘. This is deprecated.警告处理,jdbc更新处
    mybatis+oracle添加数据时如果数据存在就更新,如果不存在就插入
    条件查询器Wrapper
    查询和删除
    时间和悲观锁
  • 原文地址:https://www.cnblogs.com/fanBlog/p/12626923.html
Copyright © 2011-2022 走看看