前言
在 Spring IoC:invokeBeanFactoryPostProcessors 详解 中我们介绍了 invokeBeanFactoryPostProcessors 方法,而本文将介绍另一个类似的方法——registerBeanPostProcessors。
invokeBeanFactoryPostProcessors 方法主要用于处理 BeanFactoryPostProcessor 接口,而 registerBeanPostProcessors 方法主要用于处理BeanPostProcessor接口。BeanFactoryPostProcessor 和 BeanPostProcessor,相信大家很容易从命名看出来这两个接口“长得很像”。BeanFactoryPostProcessor 是针对 BeanFactory 的扩展,主要用在 bean 实例化之前,读取 bean 的定义,并可以修改它。BeanPostProcessor 是针对 bean 的扩展,主要用在 bean 实例化之后,执行初始化方法前后,允许开发者对 bean 实例进行修改。
概述
本方法会注册所有的BeanPostProcessor,将所有实现了BeanPostProcessor 接口的类加载到 BeanFactory中。BeanPostProcessor 接口是 Spring初始化bean 时对外暴露的扩展点,Spring IoC容器允许 BeanPostProcessor在容器初始化 bean 的前后,添加自己的逻辑处理。在registerBeanPostProcessors方法只是注册到BeanFactory 中,具体调用是在 bean 初始化的时候。
具体的:在所有 bean实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用所有 BeanPostProcessor的 postProcessAfterInitialization 方法。
正文
首先我们回到 AbstractApplicationContext.refresh() 方法,找到代码:registerBeanPostProcessors(beanFactory),单击该行代码跳转到具体的实现。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 1.注册BeanPostProcessorPostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}
详细代码
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// 1.找出所有实现BeanPostProcessor接口的类String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// Register BeanPostProcessorChecker that logs an info message when// a bean is created during BeanPostProcessor instantiation, i.e. when// a bean is not eligible for getting processed by all BeanPostProcessors.// BeanPostProcessor的目标计数int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;// 2.添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.// 3.定义不同的变量用于区分: 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor// 3.1 priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessorList<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();// 3.2 internalPostProcessors: 用于存放Spring内部的BeanPostProcessorList<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();// 3.3 orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanNameList<String> orderedPostProcessorNames = new ArrayList<String>();// 3.4 nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanNameList<String> nonOrderedPostProcessorNames = new ArrayList<String>();// 4.遍历postProcessorNames, 将BeanPostProcessors按3.1 - 3.4定义的变量区分开for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 4.1 如果ppName对应的Bean实例实现了PriorityOrdered接口, 则拿到ppName对应的Bean实例并添加到priorityOrderedPostProcessorsBeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {// 4.2 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,// 则将ppName对应的Bean实例添加到internalPostProcessorsinternalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {// 4.3 如果ppName对应的Bean实例没有实现PriorityOrdered接口, 但是实现了Ordered接口, 则将ppName添加到orderedPostProcessorNamesorderedPostProcessorNames.add(ppName);}else {// 4.4 否则, 将ppName添加到nonOrderedPostProcessorNamesnonOrderedPostProcessorNames.add(ppName);}}// First, register the BeanPostProcessors that implement PriorityOrdered.// 5.首先, 注册实现PriorityOrdered接口的BeanPostProcessors// 5.1 对priorityOrderedPostProcessors进行排序sortPostProcessors(priorityOrderedPostProcessors, beanFactory);// 5.2 注册priorityOrderedPostProcessorsregisterBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.// 6.接下来, 注册实现Ordered接口的BeanPostProcessorsList<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();for (String ppName : orderedPostProcessorNames) {// 6.1 拿到ppName对应的BeanPostProcessor实例对象BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);// 6.2 将ppName对应的BeanPostProcessor实例对象添加到orderedPostProcessors, 准备执行注册orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {// 6.3 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,// 则将ppName对应的Bean实例添加到internalPostProcessorsinternalPostProcessors.add(pp);}}// 6.4 对orderedPostProcessors进行排序sortPostProcessors(orderedPostProcessors, beanFactory);// 6.5 注册orderedPostProcessorsregisterBeanPostProcessors(beanFactory, orderedPostProcessors);// Now, register all regular BeanPostProcessors.// 7.注册所有常规的BeanPostProcessors(过程与6类似)List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// Finally, re-register all internal BeanPostProcessors.// 8.最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)// 8.1 对internalPostProcessors进行排序sortPostProcessors(internalPostProcessors, beanFactory);// 8.2注册internalPostProcessorsregisterBeanPostProcessors(beanFactory, internalPostProcessors);// Re-register post-processor for detecting inner beans as ApplicationListeners,// moving it to the end of the processor chain (for picking up proxies etc).// 9.重新注册ApplicationListenerDetector(跟8类似,主要是为了移动到处理器链的末尾)beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}
registerBeanPostProcessors
private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {// 1.遍历postProcessorsfor (BeanPostProcessor postProcessor : postProcessors) {// 2.将PostProcessor添加到BeanFactory中的beanPostProcessors缓存beanFactory.addBeanPostProcessor(postProcessor);}}
代码块3:beanFactory.addBeanPostProcessor
@Overridepublic void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");// 1.如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面)this.beanPostProcessors.remove(beanPostProcessor);// 2.将beanPostProcessor添加到beanPostProcessors缓存this.beanPostProcessors.add(beanPostProcessor);if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {// 3.如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,// 该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessorsthis.hasInstantiationAwareBeanPostProcessors = true;}if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {// 4.如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,// 该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessorthis.hasDestructionAwareBeanPostProcessors = true;}}
该方法作用就是将 BeanPostProcessor添加到beanPostProcessors缓存,这边的先移除再添加,主要是起一个排序的作用。而hasInstantiationAwareBeanPostProcessors 和 hasDestructionAwareBeanPostProcessors变量用于指示beanFactory 是否已注册过InstantiationAwareBeanPostProcessors 和 DestructionAwareBeanPostProcessor,在之后的 IoC 创建过程会用到这两个变量,这边先有个印象。
总结
如同 invokeBeanFactoryPostProcessors 方法一样,registerBeanPostProcessors 方法的内容也比较少,核心过程在代码块1的注释已经写清楚,这边稍微总结一下。
1.整个 registerBeanPostProcessors 方法围绕 BeanPostProcessor 接口展开,和 invokeBeanFactoryPostProcessors 不同的是,invokeBeanFactoryPostProcessors 方法会直接调用 BeanFactoryPostProcessor 实现类的方法,而 registerBeanPostProcessors 方法只是将 BeanPostProcessor 实现类注册到 BeanFactory 的 beanPostProcessors 缓存中。这是因为,此时还未到 BeanPostProcessor 实现类“出场的时候”。
2.BeanPostProcessor 实现类具体的 “出场时机” 在创建 bean 实例时,执行初始化方法前后。postProcessBeforeInitialization 方法在执行初始化方法前被调用,postProcessAfterInitialization 方法在执行初始化方法后被调用。
3.BeanPostProcessor 实现类和 BeanFactoryPostProcessor 实现类一样,也可以通过实现 PriorityOrdered、Ordered 接口来调整自己的优先级。
4.registerBeanPostProcessors 方法和 invokeBeanFactoryPostProcessors 也会触发 bean 实例的创建,创建 Bean 实例是 IoC 的核心内容,之后会单独解析,目前暂不深入解析。
