Spring——BeanFactory的后置处理器

BeanFactory的后置处理器

1. BeanFactory的后置处理器是什么?

首先,Spring容器在运行的过程中,第一步肯定是创建一个BeanFactory工厂对象,这个对象来负责bean的注册,bean的创建等一系列工作。一般默认的是org.springframework.beans.factory.support.DefaultListableBeanFactory 这个类。当然这部分工作是Spring来完成的,工厂初始化完之后,为了让用户可以去做一些定制型的事情,所以提供了org.springframework.beans.factory.config.BeanFactoryPostProcessor 函数式接口,使用过程中只需要实现这个接口,然后将当前的类注册进去即可。

2. BeanFactory的后置处理器分类

共分为两类:一个是带注册功能的后置处理器,即实现org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor接口。一个是不带注册功能的后置处理器,即实现org.springframework.beans.factory.config.BeanFactoryPostProcessor 接口。
ps: BeanDefinitionRegistryPostProcessor接口是继承了BeanFactoryPostProcessor 接口

在这里插入图片描述
在这里插入图片描述

3. BeanFactory的后置处理器使用

3.1 BeanDefinitionRegistryPostProcessor 带注册功能的

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {


    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 参数registry 是 BeanDefinitionRegistry 类型的。
        // 其实真正传过来的是DefaultListableBeanFactory对象
        if (registry instanceof DefaultListableBeanFactory){
            System.out.println("true");
        }
        // 在这里,我们调用DefaultListableBeanFactory的任何API,做我们自己想做的事情。
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 参数beanFactory 是 ConfigurableListableBeanFactory 类型的。
        // 其实真正传过来的是DefaultListableBeanFactory对象
        if (beanFactory instanceof DefaultListableBeanFactory){
            System.out.println("----");
            System.out.println("true");
        }
        // 在这里,我们调用DefaultListableBeanFactory的任何API,做我们自己想做的事情。
    }
}

两次传入过来的都是DefaultListableBeanFactory对象,为什么还要搞成两个方法?其实这里涉及一个调用顺序的问题,后面会讲。

3.2 BeanFactoryPostProcessor 不带注册功能的

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 参数beanFactory 是 ConfigurableListableBeanFactory 类型的。
        // 其实真正传过来的是DefaultListableBeanFactory对象
        if (beanFactory instanceof DefaultListableBeanFactory){
            System.out.println("----");
            System.out.println("true");
        }
        // 在这里,我们调用DefaultListableBeanFactory的任何API,做我们自己想做的事情。
    }
}

用起来没什么难的。

4. BeanFactory的后置处理器IOC加载顺序。

既然需要去调用我们自己定义的BeanFactory的后置处理器,首先我们的BeanFactory的后置处理器肯定是先注册到Spring容器中,然后创建对应的对象来进行方法的调用。所以我们要搞清楚BeanFactory的后置处理器何时被注册?
在注解方式下: 首先会去加载Spring自带的BeanFactory的后置处理器,之后在解析配置类即带有@Configuration注解类的时候将自定义的BeanFactory的后置处理器注册进去,然后在调用。

4.1 Spring自带的BeanFactory的后置处理器。

在创建AnnotationConfigApplicationContext对象的时候,同时会去创建一个AnnotatedBeanDefinitionReader类,在AnnotatedBeanDefinitionReader类的构造过程中,会去注册Spring自带的BeanFactory的后置处理器。具体代码如下:

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

其实只是注册了两个BeanFactory后置处理器。一个是 ConfigurationClassPostProcessor.class,一个是EventListenerMethodProcessor.class。主要关注的是ConfigurationClassPostProcessor.class,此BeanFactory的后置处理器是解析@Configuration来使用的。自定义的后置处理器,也是在解析@Configuration后来实现注册。当然你可以手动强制性注册,野路子。

4.2 自定义的BeanFactory的后置处理器。

自定义的BeanFactory的后置处理器,正常情况是,是在解析了@Configuration后来进行注册,也就是Spring自带的ConfigurationClassPostProcessor.class执行完,自定义的就会注册完。当然你可以手动调用register方法进行注册。例如:
在这里插入图片描述

5. BeanFactory的后置处理器执行顺序,重点。

上面讲过了BeanFactory的后置处理器的注册,现在看一下BeanFactory的后置处理器的执行阶段,当然涉及到一个执行的顺序问题。
BeanFactory的后置处理器执行调用的方法在 refresh 方法中。
在这里插入图片描述
点进去看一下
在这里插入图片描述
具体代码实现如下:

// 此方法进行beanFactory的后置处理器调用,参数beanFactory是之前创建好的DefaultListableBeanFactory对象,参数beanFactoryPostProcessors,是beanFactory后置处理器对象的集合,但是这个时候是空的。
public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		// 创建一个处理器bean的set集合。
		Set<String> processedBeans = new HashSet<>();

		// 此时BeanDefinitionRegistry的null,所以此方法不会走,考虑的其他的情况,所以有这段代码。
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			// 创建一个list集合,后续用于存放已经实例化的beanFactory后置处理器。
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 首先去调用,实现了BeanDefinitionRegistryPostProcessors接口的后置处理器。并且实现了PriorityOrdered接口的。此处获取对应的对象名称。
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			// 循环判断,找出实现PriorityOrdered接口的beanFactory的后置处理器,调用优先级最高。
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 如果已经实现了,调用getBean去创建对象。Spring自己也会去调用getBean对象,不只是我们会去调用。并且放入到马上被调用的beanFactory的后置处理器中。
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					// 放入到所有的后置处理器中。
					processedBeans.add(ppName);
				}
			}
			// 进行排序,因为实现PriorityOrdered.class接口的也可以有很多个,可以根据值来设置调用的优先顺序。
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 把将要调用的beanFactory的后置处理去放入到registryProcessors中。
			registryProcessors.addAll(currentRegistryProcessors);
			// 这里开始真正的调用beanFactory的后置处理器。
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// 已经被调用后清除currentRegistryProcessors集合。
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// 再次获取一次beanFactory的后置处理器名单。
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			// 循环调用
			for (String ppName : postProcessorNames) {
				// 先判断是否已经被调用过,然后调用实现Ordered接口的beanFactory的后置处理器
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					// 依然是去创建实现了Ordered接口的beanFactory的后置处理器对象。
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					// 加入到processedBeans集合中
					processedBeans.add(ppName);
				}
			}
			// 仍然进行排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 放入到registryProcessors集合中
			registryProcessors.addAll(currentRegistryProcessors);
			// 调用实现了Odered接口的beanFactory后置处理器
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// 清除currentRegistryProcessors集合。
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			// 调用剩下的没有实现Ordered 和PriorityOrdered 接口的beanFactory的后置处理器。
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				// 获取所有的实现了BeanDefinitionRegistryPostProcessor接口的bean的后置处理器。
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				// 循环判断
				for (String ppName : postProcessorNames) {
					// 是否已经被调用过,如果没有被调用,就会被调用。
					if (!processedBeans.contains(ppName)) {
						// 创建bean对象,添加到这个集合中currentRegistryProcessors
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				// 进行排序
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				// 添加到registryProcessors集合中
				registryProcessors.addAll(currentRegistryProcessors);
				// 开始调用。具体的可以看下面。
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				// 清除集合。
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			// 因为BeanDefinitionRegistryPostProcessor接口是继承BeanFactoryPostProcessor接口的,所以我们之前只是调用了postProcessBeanDefinitionRegistry方法,还有一个postProcessBeanFactory没有调用。在此处调用。
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			// 这个没什么意义。
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			// 此处用于其他工程对象进行调用的。
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		// 获取所有实现BeanFactoryPostProcessor接口的beanFactory后置处理器。
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		// 创建三个集合,priorityOrderedPostProcessors 存放实现了priorityOrdered接口的,
		// orderedPostProcessorNames 存放实现了ordered接口的。
		// nonOrderedPostProcessorNames 没有实现任何排序接口的。
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		// 循环遍历
		for (String ppName : postProcessorNames) {
			// 出去上一个阶段调用过的。
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			// 找出实现了PriorityOrdered接口的。
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 并且此时已经创建好bean了。
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			// 找出实现了Ordered接口的。
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				// 找出没有实现排序接口的。
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		// 最先调用实现了priorityOrdered接口的,进行排序
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		// 进行调用
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		// 然后调用实现了ordered接口的。
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			// 创建了实现ordered接口的实例。
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		// 排序
		sortPostProcessors(orderedPostProcessors, beanFactory);
		// 调用
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		// 最后调用没有实现排序接口的
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			// 创建实例
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		// 进行调用。
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		// 清楚缓存, 因为beanFactory的后置处理器可能已经修改了bean的信息。
		beanFactory.clearMetadataCache();
	}
/**
	 * Invoke the given BeanDefinitionRegistryPostProcessor beans.
	 */
	private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
		// 调用实现了BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法。
		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
	}
/**
	 * Invoke the given BeanFactoryPostProcessor beans.
	 */
	private static void invokeBeanFactoryPostProcessors(
			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanFactory(beanFactory);
		}
	}

图解:
在这里插入图片描述

5. BeanFactory的后置处理器执行顺序扩展点

5.1 扩展点1 排序接口

排序接口有两种,一种是 PriorityOrdered接口,一种是Ordered接口。
在这里插入图片描述
在这里插入图片描述
由此可知,PriorityOrdered继承了Ordered类,而且实现PriorityOrdered接口的执行顺序在实现了Ordered接口之前。

5.2 PriorityOrdered 排序接口 对自定义beanFactory的后置处理器的意义

1.如果自定义BeanFactory的后置处理器,正常逻辑是在ConigurationClassPostProcessor的执行后才加载,所以一定程度上PriorityOrdered对自定义beanFactory的后置处理器没任何意义。
2.但是我们可以强行把自定义beanFactory的后置处理器的执行顺序提到ConigurationClassPostProcessor之前。具体操作:

  • 实现 PriorityOrdered接口。并且getOrder(),可以控制顺序,但是ConigurationClassPostProcessor永远是最优先的。
  • 手动注册自定义BeanFactory的后置处理器。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值