上篇我们解析了 Spring 后置器的一种 BeanFactoryPostProcessor 的接口实现 bean,这次我们解析另一种 BeanPostProcessor 接口的实现 bean 在 Spring 初始化的执行步骤。
来看 refresh() 方法:
- public void refresh() throws BeansException,
- IllegalStateException {
- synchronized(this.startupShutdownMonitor) {
- // Prepare this context for refreshing.
- //设置环境变量和容器的开关标志
- prepareRefresh();
- // Tell the subclass to refresh the internal bean factory.
- //刷新beanFactory,删除旧的beanFactory,创建新的beanFactory
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
- // Prepare the bean factory for use in this context.
- // 准备beanfactory来使用这个上下文.做一些准备工作,例如classloader,beanPostProcessor等
- prepareBeanFactory(beanFactory);
- try {
- // Allows post-processing of the bean factory in context subclasses.
- postProcessBeanFactory(beanFactory);
- // Invoke factory processors registered as beans in the context.
- //执行注册到该上下文的BeanFactoryPostProcessors
- invokeBeanFactoryPostProcessors(beanFactory);
- // Register bean processors that intercept bean creation.
- //注册BeanPostProcessors,注意只是注册,和上一行不同,没有invoke
- registerBeanPostProcessors(beanFactory);
- // Initialize message source for this context.
- initMessageSource();
- // Initialize event multicaster for this context.
- initApplicationEventMulticaster();
- // Initialize other special beans in specific context subclasses.
- onRefresh();
- // Check for listener beans and register them.
- registerListeners();
- // Instantiate all remaining (non-lazy-init) singletons.
- finishBeanFactoryInitialization(beanFactory);
- // Last step: publish corresponding event.
- finishRefresh();
- } catch(BeansException ex) {
- if (logger.isWarnEnabled()) {
- logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex);
- }
- // Destroy already created singletons to avoid dangling resources.
- destroyBeans();
- // Reset 'active' flag.
- cancelRefresh(ex);
- // Propagate exception to caller.
- throw ex;
- } finally {
- // Reset common introspection caches in Spring's core, since we
- // might not ever need metadata for singleton beans anymore...
- resetCommonCaches();
- }
- }
- }
可以看到我们
就是我们要解析的方法,含义是注册 BeanPostProcessors,并没有和
- registerBeanPostProcessors
的注册过程一样,注册完就执行,这里只是注册了 BeanPostProcessors 并没有 invoke。
- BeanFactoryPostProcessor
我们跟进
- registerBeanPostProcessors(beanFactory);
- /**
- * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
- * respecting explicit order if given.
- * <p>Must be called before singleton instantiation.
- */
- protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
- PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
- }
- /**
- * Instantiate and invoke all registered BeanPostProcessor beans,
- * respecting explicit order if given.
- * <p>Must be called before any instantiation of application beans.
- */
- protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
- PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
- }
这里我留了两个方法,第一个方法是上篇的
的执行方法,第二个是 BeanPostProcessor 的执行过程,这两个后置器都是通过
- BeanFactoryPostProcessor
这个委托类来实现各自的过程的,我们打开这个委托类就会看到我们上篇的核心方法,当然也有本篇的核心方法,分别是
- PostProcessorRegistrationDelegate
- public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors)
- public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext)
我们今天分析
,这个方法的入参没有后置器集合,而是把
- registerBeanPostProcessors
实例作为参数传了进去
- AbstractApplicationContext
- public static void registerBeanPostProcessors(
- ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
- 第一步
- 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.
- int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
- beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
- // Separate between BeanPostProcessors that implement PriorityOrdered,
- // Ordered, and the rest.
- List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
- List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
- List<String> orderedPostProcessorNames = new ArrayList<String>();
- List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
- 第二步
- for (String ppName : postProcessorNames) {
- 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);
- }
- }
- 第三步
- // First, register the BeanPostProcessors that implement PriorityOrdered.
- sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
- registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
- // Next, register the BeanPostProcessors that implement Ordered.
- List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
- for (String ppName : orderedPostProcessorNames) {
- BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
- orderedPostProcessors.add(pp);
- if (pp instanceof MergedBeanDefinitionPostProcessor) {
- internalPostProcessors.add(pp);
- }
- }
- sortPostProcessors(beanFactory, orderedPostProcessors);
- registerBeanPostProcessors(beanFactory, orderedPostProcessors);
- // Now, register all regular BeanPostProcessors.
- 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.
- sortPostProcessors(beanFactory, internalPostProcessors);
- registerBeanPostProcessors(beanFactory, internalPostProcessors);
- 第四步
- beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
- }
我在源码里标注了四个步骤,接下里分别解释:
1. 通过
方法获取 beanFactory 里继承了 BeanPostProcessor 接口的 name 的集合;
- beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
2. 把后置器 beans 分为 PriorityOrdered、Ordered、nonOrdered 三大类,前两类是增加了排序条件的后置器;
3. 前两类后置器执行 sortPostProcessors 和方法,也就是先执行排序方法,后执行注册方法。 4. 最后一步用到了上面提到的 BeanPostProcessor 和
- registerBeanPostProcessors
的入参不同的
- BeanFactoryPostProcessor
,这一步执行了什么呢?
- AbstractApplicationContext
- public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
- Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
- this.beanPostProcessors.remove(beanPostProcessor);
- this.beanPostProcessors.add(beanPostProcessor);
- if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
- this.hasInstantiationAwareBeanPostProcessors = true;
- }
- if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
- this.hasDestructionAwareBeanPostProcessors = true;
- }
- }
可以看到,在 addBeanPostProcessor 方法里把 BeanPostProcessor 注册进了 AbstractBeanFactory,这也就是为什么
执行了后置接口实现类,而 BeanPostProcessor 仅仅执行了注册,而没有执行的原因。
- BeanFactoryPostProcessor
来源: http://www.jianshu.com/p/94bb61bc53d8