Spring IOC源码分析1——关注bean实例化和增强

0.调试示例

以 Bean生命周期 为例

Jeep.java

@Component
public class Jeep {
    public Jeep(){
        System.out.println("Jeep.....constructor........");
    }
    @PostConstruct
    public void init(){
        System.out.println("[email protected]");
    }

    @PreDestroy
    public void destory(){
        System.out.println("[email protected]");
    }

}

实现后置处理器接口BeanPostProcessor的JamesBeanPostProcessor.java

@Component
public class JamesBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //返回一个的对象(传过来的对象)
        //在初始化方法调用之前进行后置处理工作,
        //什么时候调用它: init-method=init之前调用
        System.out.println("postProcessBeforeInitialization...."+beanName+"..."+bean);
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization...."+beanName+"..."+bean);
        return bean;
    }
}

1.创建业务类bean的流程以及后置处理器的执行时机

创建业务类bean的关键流程如下(AbstractAutowireCapableBeanFactory.java / doCreateBean()方法):

  • step1.调用Jeep()的默认构造函数——createBeanInstance(beanName, mbd, args)
  • step2.给各种属性赋值——populateBean(beanName, mbd, instanceWrapper)
  • step3.初始化bean——initializeBean(beanName, exposedObject, mbd)
    step3-1.调用invokeAwareMethods(beanName, bean)
    step3-2.调用后置处理器applyBeanProcessorsBeforeInitialization
    step3-3.指定的初始化方法进行初始化
    step3-4.调用后置处理器applyBeanPostProcessorsAfterInitialization
  • step4.销毁bean之前,调用后置处理器的方法进行处理

step1.调用Jeep()的默认构造函数——createBeanInstance(beanName, mbd, args)

获取到Jeep的默认构造函数,然后调用该默认构造函数,创建Jeep的实例对象。

  • 调用栈如下:


    Spring IOC源码分析1——关注bean实例化和增强_第1张图片

    Spring IOC源码分析1——关注bean实例化和增强_第2张图片
  • 调用结果:


    Spring IOC源码分析1——关注bean实例化和增强_第3张图片

step2.给各种属性赋值——populateBean(beanName, mbd, instanceWrapper)

Jeep没有对各属性进行赋值,因此,这里没有进行处理。

step3.初始化bean——initializeBean(beanName, exposedObject, mbd)

step3-1.调用invokeAwareMethods(beanName, bean)

Jeep这一步没有任何操作。

step3-2.调用后置处理器applyBeanProcessorsBeforeInitialization

后置处理器的个数,处理顺序,也是按照如下的列表顺序进行逐个处理的:


Spring IOC源码分析1——关注bean实例化和增强_第4张图片

这里有两个后置处理器进行处理:

1)JamesBeanPostProcessor

  • 调用栈


    Spring IOC源码分析1——关注bean实例化和增强_第5张图片

    Spring IOC源码分析1——关注bean实例化和增强_第6张图片
  • 调用结果:


2)InitDestroyAnnotationBeanPostProcessor对@PostConstruct的处理

InitDestroyAnnotationBeanPostProcessor是使用CommonAnnotationBeanPostProcessor进行调用的。

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable 
  • 调用栈


    Spring IOC源码分析1——关注bean实例化和增强_第7张图片

    Spring IOC源码分析1——关注bean实例化和增强_第8张图片
  • 调用结果:


    Spring IOC源码分析1——关注bean实例化和增强_第9张图片

step3-3.指定的初始化方法进行初始化

Jeep没有指定初始化方法。

step3-4.调用后置处理器applyBeanPostProcessorsAfterInitialization

这里只有1个后置处理器进行处理:

1)JamesBeanPostProcessor

  • 调用栈:


    Spring IOC源码分析1——关注bean实例化和增强_第10张图片

    Spring IOC源码分析1——关注bean实例化和增强_第11张图片
  • 调用结果:


step4.销毁bean之前,调用后置处理器的方法进行处理

这里只有1个后置处理器进行处理:

1)InitDestroyAnnotationBeanPostProcessor对@PreDestroy的处理

  • 调用栈:


    Spring IOC源码分析1——关注bean实例化和增强_第12张图片
  • 调用结果:


2.后置处理器的创建流程

Spring IOC源码分析1——关注bean实例化和增强_第13张图片

2.1 CommonAnnotationBeanPostProcessor的创建

  • 该后置处理器创建的调用栈
    其getBean()与业务getBean()是一模一样的。


    Spring IOC源码分析1——关注bean实例化和增强_第14张图片

    Spring IOC源码分析1——关注bean实例化和增强_第15张图片

2.2 JamesBeanPostProcessor的穿件

  • 调用栈(同上,都是调用getBean()创建)


    Spring IOC源码分析1——关注bean实例化和增强_第16张图片

    Spring IOC源码分析1——关注bean实例化和增强_第17张图片

其他说明

1)priorityOrderedPostProcessors,orderedPostProcessors和nonOrderedPostProcessors
三种排序类型的后置处理器,先处理priorityOrderedPostProcessors,最后处理nonOrderedPostProcessors;
加入ConfigurableListableBeanFactory beanFactory的beanPostProcessors是按顺序依次加入到末尾位置。

3.总结

参考

  • 1)享学课堂James老师笔记

你可能感兴趣的