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是怎麼使用的了。