• 7.6、bean的周期10步源码解析


    image.png

    1、1,2步

    对于初始化对象 + 注入属性

    • 初始化创建对象,反射调用无参数构造方法,第一步
      Object bean = instanceWrapper.getWrappedInstance();

    • Bean的属性setter注入值,执行setter方法,第二步
      populateBean(beanName, mbd, instanceWrapper);

    public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
    		implements AutowireCapableBeanFactory {
        
    	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
              throws BeanCreationException {
    
           // Instantiate the bean.
           BeanWrapper instanceWrapper = null;
           if (mbd.isSingleton()) {
              instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
           }
           if (instanceWrapper == null) {
           	   //实例化创建对象,反射调用无参数构造方法,第一步
              instanceWrapper = createBeanInstance(beanName, mbd, args);
           }
           //获取bean对象
           Object bean = instanceWrapper.getWrappedInstance();
    
           // Initialize the bean instance.
           Object exposedObject = bean;
    
            //......
    
           try {
               //给Bean的属性setter注入值,执行setter方法,第二步
              populateBean(beanName, mbd, instanceWrapper);
               //暴露对象,主要是在这里
              exposedObject = initializeBean(beanName, exposedObject, mbd);
           }
            
           //.....
            return exposedObject;
        }
        
        //.....
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    2、3-7步

    image-20221111002521251


    第3步:点位1,实现Aware接口

    exposedObject = initializeBean(beanName, exposedObject, mbd);

    进入本类的initializeBean方法进行初始化对象,调用invokeAwareMethods

    其中invokeAwareMethods方法就是判断Bean类是否实现了Aware接口中的三者。

    然后执行相关的方法即可

    image-20221111001648916


    第4步:实现 BeanPostProcessor调用before方法

    遍历找实现了BeanPostProcessor的接口的类,并调用相应的postProcessBeforeInitialization方法

    在这里我们是自己创建的类LogBeanPostProcessor

    image-20221111002558396

    public class LogBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("第三步:执行Bean后处理器的before方法");
            return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    
            System.out.println("第五步:执行Bean后处理器的after方法");
            return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    第5步:对于点位2,实现InitializingBean

    初始化方法,调用相应实现了该接口的afterPropertiesSet方法

    image-20221111003116519

    第6步:反射调用自己的初始化方法

    image-20221111005252623

    image-20221111005403712

    第7步:调用before处理器的after 方法

    同理 before方法

    image-20221111005509629

    3、8-10步

    第 8 步,使用bean对象

    image-20221111005829099

    第9步,实现DisposableBean接口,调用接口方法,第10步,删除自己的myDistroy方法

    主要是DefaultSingletonBeanRegistry 类,调用beandistroy方法

    image-20221111013105554

    然后再销毁bean对象的 destroyBean

    protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
       // Trigger destruction of dependent beans first...
       Set<String> dependencies;
       synchronized (this.dependentBeanMap) {
          // Within full synchronization in order to guarantee a disconnected Set
          dependencies = this.dependentBeanMap.remove(beanName);
       }
       if (dependencies != null) {
          if (logger.isTraceEnabled()) {
             logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
          }
          for (String dependentBeanName : dependencies) {
             destroySingleton(dependentBeanName);
          }
       }
    
       // Actually destroy the bean now...
       if (bean != null) {
          try {
              //第9步,销毁bean对象--------------------------
             bean.destroy();
          }
          catch (Throwable ex) {
             if (logger.isWarnEnabled()) {
                logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
             }
          }
       }
    
        //从containedBeanMap中删除bean对象 (containedBeanMap)
    	//....
        //删除bean对象的依赖的其他bean对象 (dependentBeanMap)
    	//....  
        //删除已销毁的 Bean 准备好的依赖项信息。
        //....
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    具体调用 bean.destroy()方法 进行 bean的销毁操作

    进入DisposableBeanAdapterdestroy方法进行销毁

    image-20221111015822843

    说明:DisposableBeanAdapter 里面持有了bean对象,

    image-20221111014140518

    ①对于DisposableBeanAdapter 类如何创建的呢?

    • 其实在下面和销毁的bean加入的disposableBeans map 是在同一个方法进行创建的,以beanName作为keyDisposableBeanAdapter作为value 加入到 map

    ②销毁的bean何时加入的disposableBeans map中的呢?

    • 主要是在创建bean对象后,

    • doCreate方法里面有一个registerDisposableBeanIfNecessary(beanName, bean, mbd);

    • 其中mbd就是RootBeanDefinition类的对象,说白了存放的就是当前bean对象

    	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    			throws BeanCreationException {
            
            //.....
            // Register bean as disposable.
    		try {
                //注册到销毁bean的map里面
    			registerDisposableBeanIfNecessary(beanName, bean, mbd);
    		}
    		catch (BeanDefinitionValidationException ex) {
    			throw new BeanCreationException(
    					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    		}
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意的是:bean的类型不能是原型,原型的不能进行销毁。

    image-20221111012350684


    image-20221111015442623

    测试: bean的类型不能是原型,原型的不能进行销毁。

    <bean class="com.cjf.bean.LogBeanPostProcessor"/>
    <bean id="user" class="com.cjf.bean.User" init-method="initBean" destroy-method="myDestroy" scope="prototype">
        <property name="name" value="zs"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4

    image-20221111022022652

    通过测试我们也可以验证原型的bean是不会调用相应的及自己的销毁方法的

  • 相关阅读:
    设计模式-访问者模式(Visitor)
    Windows 上杀端口和相关进程
    POJ2031空间站题解
    Centos 停服倒计时!你的操作系统何去何从?
    Java中&和&&的区别
    centos-apache-简易搭建静态网页服务器-总结
    delegate使用方法C#(Demo)
    Problem C: 凯撒加密
    AM驱动架构—优质Mini-LED显示技术解决方案
    Ellipse
  • 原文地址:https://blog.csdn.net/qq_67720621/article/details/127799054