Spring - BeanPostProcessor 接口

最近在查看Spring Boot启动源码,学习重要的 AbstractApplicationContextrefresh() 方法,发现其中有个关于 bean 创建时拦截的知识点。

一、接口定义

先查看 BeanPostProcessor接口定义。

// 允许自定义修改一个bean 的实例化的工厂钩子
// 注册:ApplicationContext 获取 BeanPostProcessor 的 bean,并且应用于之后的所有 bean 的创建
// 排序:BeanPostProcessor  根据实现的 Ordered 或 PriorityOrdered 或都不实现进行排序
public interface BeanPostProcessor {

	// 在 bean 实例化调用任何初始化回掉之前执行。如 InitializingBean#afterPropertiesSet 或者 @PostConstruct 
	// 参数:bean bean实例  beanName bean 名称
	// 返回:使用的bean 实例。如果为null,就不执行后续的 BeanPostProcessors 处理
	@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;
	}
}

二、源码实现

再查看具体源码实现
AbstractApplicationContext

	public void refresh() throws BeansException, IllegalStateException {
	/*...*/
		// Register bean processors that intercept bean creation.
		// 注册 bean 处理器来拦截 bean 的创建
		registerBeanPostProcessors(beanFactory);
	/*...*/
}

查看方法
Spring - BeanPostProcessor 接口

方法注释:实例化并且注册所有的 BeanPostProcessor bean,并且如果有给定顺序,要按照给定顺序执行。
必须在任何 application bean 实例化之前调用。

这里有一点,application 对应 bean 的 role,分为 BeanDefinition#ROLE_APPLICATION
BeanDefinition#ROLE_INFRASTRUCTUREBeanDefinition#ROLE_SUPPORT

再接着跟进查看方法

	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		// 获取容器中的所有实现 BeanPostProcessor 的bean的名字
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
		
		// 手动添加一个 BeanPostProcesser 的bean实例到处理链中
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 这里根据实现 BeanPostProcessors 的实现类是否同时实现了 PriorityOrdered 接口,
		// Ordered 接口 或者都没有实现 来进行区分
		// 实现了 PriorityOrdered 接口的
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		// 实现了 Ordered 接口的
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// 两个接口都没有实现的
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			// 遍历所有的 BeanPostProcessor 的bean,然后根据 排序 添加到不同的集合里面
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				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);
			}
		}

		// 这里根据实现了 PriorityOrdered 接口的 BeanPostProcesser 实例进行排序后,
		// 优先添加到 BeanPostProcesser  的处理链中
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 然后排序处理实现了 Ordered 接口的 BeanPostProcesser 实例 添加到处理链中
		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);

		//最后再处理其它的
		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);

		// 最后在处理链末尾手动添加一个 处理器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

到这里说明了 BeanPostProcessor的添加顺序。

三、测试执行顺序

测试一

// 新建一个bean 实现了 InitializingBean 接口,并且有一个 @PostConstruct 标注的初始化方法。打印所执行的方法。
@Component
public class InitializingBeanImplTest implements InitializingBean {
    // 构造函数
    public InitializingBeanImplTest() {
        System.out.println(InitializingBeanImplTest.class.getName() + "#Constructor");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(InitializingBeanImplTest.class.getName() + " :: " + InitializingBean.class.getName() + "#afterPropertiesSet");
    }
    @PostConstruct
    public void init() {
        System.out.println(InitializingBeanImplTest.class.getName() + " :: " + PostConstruct.class.getName());
    }
}

// 新建一个 bean 实现 BeanPostProcessorImplTest 接口,重写两个方法。打印类名和执行方法名称
@Component
public class BeanPostProcessorImplTest implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(BeanPostProcessorImplTest.class.getSimpleName() + " :: " + bean.getClass().getName() + "#postProcessBeforeInitialization");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(BeanPostProcessorImplTest.class.getSimpleName() + " :: " + bean.getClass().getName() + "#postProcessAfterInitialization");
        return bean;
    }
}

执行结果
Spring - BeanPostProcessor 接口
有两个点:
1、 BeanPostProcessorImplTest 利用编辑器查找匹配 604 次
2、执行顺序:构造函数 -> postProcessBeforeInitialization -> @PostConstruct -> InitializingBean#afterPropertiesSet -> postProcessAfterInitialization

测试二
修改 BeanPostProcessorImplTest,实现 Ordered 接口,并且设置最高优先权

@Component
public class BeanPostProcessorImplTest implements BeanPostProcessor, Ordered {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(BeanPostProcessorImplTest.class.getSimpleName() + " :: " + bean.getClass().getName() + "#postProcessBeforeInitialization");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(BeanPostProcessorImplTest.class.getSimpleName() + " :: " + bean.getClass().getName() + "#postProcessAfterInitialization");
        return bean;
    }
	// 设置最高优先权
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

结果:
Spring - BeanPostProcessor 接口

BeanPostProcessorImplTest 利用编辑器查找匹配 616 次。比未实现匹配次数多。

测试三
修改 BeanPostProcessorImplTest,修改 Ordered 接口,为 PriorityOrdered 并且设置最高优先权
Spring - BeanPostProcessor 接口

BeanPostProcessorImplTest 利用编辑器查找匹配 624 次,比实现Ordered匹配次数多。

四、总结

1、BeanPostProcessor bean 作用于 每个后续bean 的创建。提供自定义更改。可通过 Ordered或者 PriorityOrdered 接口设置 BeanPostProcessor bean 在处理链中的位置。
2、对于普通bean,执行顺序是构造函数 -> postProcessBeforeInitialization -> @PostConstruct -> InitializingBean#afterPropertiesSet -> postProcessAfterInitialization

上一篇:Spring后置处理器BeanPostProcessor


下一篇:10、spring注解学习(bean的生命周期)——BeanPostProcessor【接口】:bean的后置处理器