12-Spring源码解析之refresh(5)——registerBeanPostProcessors

Spring版本:<version>5.2.1.RELEASE</version>

上一篇:11-Spring源码解析之refresh(4)——invokeBeanFactoryPostProcessors(2)

上一篇,我们介绍完了Spring是如何注册BeanFactoryPostProcessors,如何解析@Configuration注解标注的配置类,如何将配置类中的类信息放到beanFactory.beanDefinitionMap中。

本篇我们继续讲解refresh方法中调用的第六个方法:registerBeanPostProcessors -> 注册BeanPostProcessor。注意,这里是注册,注册!而不是调用,真正的调用是在Bean实例化阶段进行的。BeanPostProcessor是Spring提供的扩展接口。

在讲解registerBeanPostProcessors之前,我们需要先了解BeanPostProcessor的结构,以及他的功能是什么。

一、 BeanPostProcessor简介

public interface BeanPostProcessor {
	// bean初始化方法调用前被调用
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	
	// bean初始化方法调用后被调用
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

从上面可以看出,BeanPostProcessor接口只提供了两个方法,这两个方法分别是在Bean初始化前后调用。为了更有力的说明BeanPostProcessor执行时机,我给出以下实例。

1. BeanPostProcessor实例

自定义后置处理器MyBeanPostProcessor


// 使用@Component将后置处理器加入到容器中
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    // 初始化之前进行处理
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("beforeInitializtion....." + beanName);
        return bean;
    }
    // 初始化之后进行处理
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("afterInitializtion....." + beanName);
        return bean;
    }
}

注意:实现接口中的两个方法的最后返回值不能返回null,如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bean实例对象,因为后置处理器从Spring容器中取出bean实例对象没有再次放回Spring容器中。

POJO


public class MathCalculator {
    private String name;

    public MathCalculator(String name) {
        this.name = name;
        System.out.println("pojo类的构造方法");
    }

    public void init() {
        System.out.println("pojo类的init方法");
    }

    public int div(int i, int j) {
        return i / j;
    }

    @Override
    public String toString() {
        return "MathCalculator{" +
                "name='" + name + '\'' +
                '}';
    }
}

该类有一个属性name,一个有参构造器,为了方便看BeanPostProcessor的执行顺序,一个init方法,这个init在配置类中我会将其标志为初始化方法,一个toStrng,一个div方法,这个div方法是为了测试AOP,这里暂时用不到。

配置类Config_beanPostProcessor

@ComponentScan
@Configuration
public class Config_beanPostProcessor {
    @Bean(initMethod = "init")
    public Pojo pojo() {
        System.out.println("给容器中添加 Pojo");
        return new Pojo("pojo.Name属性");
    }
}

测试类

public class beanPostProcessorTest {
    @SuppressWarnings("resource")
    @Test
    public void test01() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config_beanPostProcessor.class);
        Pojo pojo = applicationContext.getBean(Pojo.class);
        System.out.println(pojo);
    }
}

输出结果

在这里插入图片描述
我们可以看到BeanPostProcessor的实现类中的两个方法在配置类和pojo类中都有调用。我们主要看在POJO类的调用顺序:
这里还涉及另外一个问题:因为pojo类是由配置类通过@Bean方式加入到Spring容器中的,因此在做doCreateBean - > createBeanInstance 与普通的Bean不一样。具体有什么不同,在后面的文章会介绍。

另外,从上面输出结果也可以看出,BeanPostProcessor实现类会拦截每一个Bean的创建,并在Bean的初始化前后调用postProcessBeforeInitializationpostProcessAfterInitialization方法。

回到上面的输出结果,我们可以看出BeanPostProcessor类的方法的调用顺序如下:

在这里插入图片描述

2. BeanPostProcessor的类结构

看完了BeanPostProcessor的执行顺序,下面我们看一下SpringBeanPostProcessor的类结构

在这里插入图片描述

Spring中有5大类BeanPostProcessor,每一类在加载Bean的时候都起着十分重要的作用。这里先不具体介绍,我们先把整体流程看完之后,在后面会具体总结每一个BeanPostProcessorSpring中的调用时机。

现在已经了解到BeanPostProcessor的结构以及调用顺序了,我们就可以开始分析Spring是如何将BeanPostProcessor注册到beanFactoy中的了。

二、BeanPostProcessor注册

2.1 当前beanFactory中的值

终于来到了正题:refresh调用的第六个方法registerBeanPostProcessors。那么在看这个方法的具体实现之前,我们还是得先看看当前beanFactory中都注册了哪些beanDefinition,有哪些beanPostProcessor和已经创建了哪些Bean

在这里插入图片描述
从上图可以看出有10个beanDefinition,其中

  • beanDefinition[0] -- beanDefinition[4]为Spring内置的Bean
  • beanDefinition[5]为我们自己写的配置类,
  • beanDefinition[6]为我们自己写的实现了BeanPostProcessor的类,
  • beanDefinition[7]为我们自己写的pojo类,
  • beanDefinition[8]为我们自己写的切面类(为了做AOP),
  • beanDefinition[9]Spring为了实现AOP功能为我们创建的内置类。

接下来看看当前BeanFactory中已经有哪些后置处理器
在这里插入图片描述

beanPostProcessors[0]beanPostProcessors[1]refresh()调用的prepareBeanFactory()方法中通过beanFactory.addBeanPostProcessor添加的。具体参见:9-Spring容器创建之refresh(3)——【prepareBeanFactory】与【postProcessBeanFactory】beanPostProcessor[2]refresh调用的invokeBeanFactoryPostProcessors()方法的时候调用beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));添加的。

继续看当前BeanFactory已经创建好哪些Bean
在这里插入图片描述
看完了以上3个属性之后,我们就可以开始分析registerBeanPostProcessors是如何实现的了!以及执行完registerBeanPostProcessors方法后,beanFactory中的以上三个属性增加了些什么。

2.2 registerBeanPostProcessors方法

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

调用PostProcessorRegistrationDelegate类的方法registerBeanPostProcessors,记得在refresh调用第五个方法invokeBeanFactoryPostProcessors的时候吗?也是调用了PostProcessorRegistrationDelegate类的方法,只不过那个时候调用的是:invokeBeanFactoryPostProcessors方法

	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		// 根据BeanPostProcessor类型从beanFactory获取beanName
		// 从2.1中的图知道,beanFactory的10个bean中有4个是BeanPostProcessor类型的,具体哪4个在这一节最后的图片中给出
		//   其中3个内置类已经注册完了。
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 向beanFactory中又注册了一个BeanPostProcessorChecker类型的BeanPostProcessor
		// beanProcessorTargetCount:为当前BeanPostProcessor总数+1(+1是刚刚又加了一个BeanPostProcessorChecker类型的BeanPostProcessor)
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 将所有的BeanPostProcessor按照优先级(PriorityOrdered、Ordered)归类
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 内置类就正常按照doGetBean的顺序进行创建
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// ---------------------------------2.2.1具体讲解registerBeanPostProcessors方法
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// ---------------------------------2.2.2简要介绍AOP的AnnotationAwareAspectJAutoProxyCreator----
		// Next, register the BeanPostProcessors that implement Ordered.
		// 注意,实现AOP功能的AnnotationAwareAspectJAutoProxyCreator类在这个地方被创建,
		// 在这里创建的原因:因为他是实现了Ordered接口的BeanPostProcessor
		// 这里不详细介绍,在AOP文章中会详细介绍。但是在这里给出一下AnnotationAwareAspectJAutoProxyCreator的类图
		//----------------------------------AOP在这里创建-------------------------------------
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		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.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(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).
		// 最后又重新注册了一次ApplicationListenerDetector,我们知道在refresh-> prepareBeanFactory方法中已经注册过一次了
		// 那么为什么还要再注册一次呢?
		// 主要是想要将ApplicationListenerDetector放到所有的BeanPostProcessor最后
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

registerBeanPostProcessors执行之前,我们看以下beanFactory中的beanDefinition中有哪些BeanPostProcessor。这些BeanPostProcessor还没有被注册。
在这里插入图片描述
从上面可以看出,registerBeanPostProcessors方法就是将beanFactorypostProcessor都注册到BeanPostProcessor中。另外还给beanFactory多增加了一个BeanPostProcessor,即BeanPostProcessorChecker

在执行完registerBeanPostProcessors之后,我们看一下beanFactory中有哪些BeanPostProcessor

在这里插入图片描述

以上是调用registerBeanPostProcessors方法之前beanFactory中存在的BeanPostProcessor。下面我们看一下调用registerBeanPostProcessors之后beanFactory中存在的BeanPostProcessor

  • beanPostProcessor[3]beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));添加
  • beanPostProcessor[4]Ordered接口添加
  • beanPostProcessor[5]regular处添加
  • beanPostProcessor[6] - beanPostProcessor[7]PriorityOrdered接口添加

在执行完registerBeanPostProcessors方法后,beanFactory中已经创建的Bean如下:

在这里插入图片描述
其中myBeanPostProcessor为我们自己写的实现了BeanPostProcessor的类。

2.2.1 registerBeanPostProcessors方法

	private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
		// 将每一个BeanPostProcessor添加到beanFactory的BeanPostProcessor中
		for (BeanPostProcessor postProcessor : postProcessors) {
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}
	public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
		Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
		// Remove from old position, if any
		this.beanPostProcessors.remove(beanPostProcessor);
		// 如果当前的beanPostProcessor是InstantiationAwareBeanPostProcessor类型,就要将beanFactory的hasInstantiationAwareBeanPostProcessors属性设置为true
		// 这个属性在创建Bean的时候会用到: createBean -> resolveBeforeInstantiation
		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
			this.hasInstantiationAwareBeanPostProcessors = true;
		}
		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
			this.hasDestructionAwareBeanPostProcessors = true;
		}
		// Add to end of list
		// 将beanPostProcessor放到beanFactory的beanPostProcessors属性中
		// private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
		this.beanPostProcessors.add(beanPostProcessor);
	}

2.2.2 AnnotationAwareAspectJAutoProxyCreator

这里面涉及到AOP功能对应的AnnotationAwareAspectJAutoProxyCreator类型的Bean的创建,为什么在这里呢?因为实现AOP功能AnnotationAwareAspectJAutoProxyCreator就是一个实现了Ordered接口的BeanPostProcessor。这里不详细讲解他的创建过程,在之后的AOP文章中具体介绍。

在这里插入图片描述

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

他的父类ProxyProcessorSupport实现了Ordered接口:

public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean

三、总结

  • registerBeanPostProcessors 的功能:
    • 【功能一】为beanFactory直接添加 BeanPostProcessorChecker后置处理器
    • 【功能二】按照顺序实例化BeanPostProcessors并将其添加到beanFactoryBeanPostProcessors
    • 【功能三】将ApplicationListenerDetector后置处理器移到后置处理器集合的最后

以上我们完成了registerBeanPostProcessors功能的分析,下一篇我们继续分析refresh方法中的

  • 第七个方法initMessageSource
  • 第八个方法initApplicationEventMulticaster
  • 第九个方法onRefresh
  • 第十个方法registerListeners
发布了397 篇原创文章 · 获赞 71 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/xiaojie_570/article/details/104690798