1. 程式人生 > 實用技巧 >Spring原始碼解析(三) -- registerBeanPostProcessors(beanFactory)

Spring原始碼解析(三) -- registerBeanPostProcessors(beanFactory)

  本節分析下 refresh()中的registerBeanPostProcessors(beanFactory);方法

  

public interface BeanPostProcessor {

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 */
	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
	 * instance and the objects created by the FactoryBean (as of Spring 2.0). The
	 * post-processor can decide whether to apply to either the FactoryBean or created
	 * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
	 * <p>This callback will also be invoked after a short-circuiting triggered by a
	 * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
	 * in contrast to all other BeanPostProcessor callbacks.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 * @see org.springframework.beans.factory.FactoryBean
	 */
	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}

  BeanPostProcessor的作用是一個 在BeanDefinition例項化成一個真正的物件後,在該物件的初始化前和初始化後做一些工作。它和BeanFactoryPostProcess不同,BeanFactoryPostProcess一般是改變下某個BeanDefinition,而不是真的物件。

  跟著程式碼,發現實際呼叫的是PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);

  

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>();

  其實跟上一節的beanFactoryPostProcessor過程類似,在查詢BeanPostProcessor的Bean 名字時,都是按照PriorityOrdered,Ordered, 和沒有顯示這兩個介面的類的順序,依次例項化和初始化生成這些bean,並且註冊到beanFactory中

  AbstractBeanFactory中的方法addBeanPostProcessor,注意是 先 remove再 add

     @Override
	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;
		}
	}

  回到registerBeanPostProcessors方法中 裡面有一個特別需要注意的地方

  

if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}

  如果某一個BeanPostProcessor實現了MergedBeanDefinitionPostProcessor這個介面,把它單獨的放到internalPostProcessors這個list中儲存起來,並且在例項化,並註冊到了beanFactory之後,最後再做一次把這些MergedBeanDefinitionPostProcessor註冊進去

  

// Finally, re-register all internal BeanPostProcessors.
        sortPostProcessors(beanFactory, internalPostProcessors);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

所以,我們之前說註冊時先remove再add,這樣就能保證這些internal BeanPostProcessors肯定是在AbstractBeanFactory中儲存所有beanPostProcessor的最後。

  MergedBeanDefinitionPostProcessor的實現類有哪些呢?

  比較常見的有兩個AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor

  AutowiredAnnotationBeanPostProcessor就是用來處理一個spring bean中autowired註解的,而CommonAnnotationBeanPostProcessor是處理resource註解的。resource註解是java的不是spring的。

  下一節,會分析beanFactory例項化的程式碼,就能夠看到beanPostProcessor是怎麼使用的了。