`

Spring的BeanFactoryPostProcessor和BeanPostProcessor

 
阅读更多

http://blog.csdn.net/caihaijiang/article/details/35552859

 

BeanFactoryPostProcessor和BeanPostProcessor,这两个接口,都是Spring初始化bean时对外暴露的扩展点。两个接口名称看起来很相似,但作用及使用场景却不同,分析如下:

1、BeanFactoryPostProcessor接口

该接口的定义如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public interface BeanFactoryPostProcessor {  
  2.   
  3.     /** 
  4.      * Modify the application context's internal bean factory after its standard 
  5.      * initialization. All bean definitions will have been loaded, but no beans 
  6.      * will have been instantiated yet. This allows for overriding or adding 
  7.      * properties even to eager-initializing beans. 
  8.      * @param beanFactory the bean factory used by the application context 
  9.      * @throws org.springframework.beans.BeansException in case of errors 
  10.      */  
  11.     void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;  
  12.   
  13. }  

实现该接口,可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。
注意:BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的。接口方法的入参是ConfigurrableListableBeanFactory,使用该参数,可以获取到相关bean的定义信息,例子:

 

1)spring bean的定义:

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  7.                 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
  8.                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"  
  9.     default-autowire="byName">  
  10.       
  11.     <bean id="myJavaBean" class="com.ali.caihj.postprocessor.MyJavaBean">  
  12.         <property name="desc" value="测试一下啦" />  
  13.         <property name="remark" value="这是备注信息啦啦啦" />  
  14.     </bean>  
  15.     <bean id="myBeanFactoryPostProcessor" class="com.ali.caihj.postprocessor.MyBeanFactoryPostProcessor" />  
  16. </beans>  

 

2)自定义的BeanFactoryPostProcessor:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {  
  2.   
  3.     public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {  
  4.         System.out.println("调用MyBeanFactoryPostProcessor的postProcessBeanFactory");  
  5.         BeanDefinition bd = beanFactory.getBeanDefinition("myJavaBean");  
  6.         System.out.println("属性值============" + bd.getPropertyValues().toString());  
  7.         MutablePropertyValues pv =  bd.getPropertyValues();    
  8.         if (pv.contains("remark")) {    
  9.             pv.addPropertyValue("remark""把备注信息修改一下");    
  10.         }    
  11.         bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);  
  12.     }  
  13.   
  14. }  

spring中,有内置的一些BeanFactoryPostProcessor实现类,常用的有:

  • org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
  • org.springframework.beans.factory.config.PropertyOverrideConfigurer
  • org.springframework.beans.factory.config.CustomEditorConfigurer:用来注册自定义的属性编辑器

 

2、BeanPostProcessor接口

该接口的定义如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public interface BeanPostProcessor {  
  2.   
  3.     /** 
  4.      * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean 
  5.      * initialization callbacks (like InitializingBean's <code>afterPropertiesSet</code> 
  6.      * or a custom init-method). The bean will already be populated with property values. 
  7.      * The returned bean instance may be a wrapper around the original. 
  8.      * @param bean the new bean instance 
  9.      * @param beanName the name of the bean 
  10.      * @return the bean instance to use, either the original or a wrapped one 
  11.      * @throws org.springframework.beans.BeansException in case of errors 
  12.      * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet 
  13.      */  
  14.     Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;  
  15.   
  16.     /** 
  17.      * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean 
  18.      * initialization callbacks (like InitializingBean's <code>afterPropertiesSet</code> 
  19.      * or a custom init-method). The bean will already be populated with property values. 
  20.      * The returned bean instance may be a wrapper around the original. 
  21.      * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean 
  22.      * instance and the objects created by the FactoryBean (as of Spring 2.0). The 
  23.      * post-processor can decide whether to apply to either the FactoryBean or created 
  24.      * objects or both through corresponding <code>bean instanceof FactoryBean</code> checks. 
  25.      * <p>This callback will also be invoked after a short-circuiting triggered by a 
  26.      * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method, 
  27.      * in contrast to all other BeanPostProcessor callbacks. 
  28.      * @param bean the new bean instance 
  29.      * @param beanName the name of the bean 
  30.      * @return the bean instance to use, either the original or a wrapped one 
  31.      * @throws org.springframework.beans.BeansException in case of errors 
  32.      * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet 
  33.      * @see org.springframework.beans.factory.FactoryBean 
  34.      */  
  35.     Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;  
  36.   
  37. }  

BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:

 

1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet

2)在bean定义的时候,通过init-method设置的方法

注意:BeanPostProcessor是在spring容器加载了bean的定义文件并且实例化bean之后执行的。BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后。

spring中,有内置的一些BeanPostProcessor实现类,例如:

  • org.springframework.context.annotation.CommonAnnotationBeanPostProcessor:支持@Resource注解的注入
  • org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor:支持@Required注解的注入
  • org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor:支持@Autowired注解的注入
  • org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor:支持@PersistenceUnit和@PersistenceContext注解的注入
  • org.springframework.context.support.ApplicationContextAwareProcessor:用来为bean注入ApplicationContext等容器对象

这些注解类的BeanPostProcessor,在spring配置文件中,可以通过这样的配置 <context:component-scan base-package="*.*" /> ,自动进行注册。(spring通过ComponentScanBeanDefinitionParser类来解析该标签

 

3、下面通过完整的一个例子,来加深理解

1)定义一个JavaBean

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public class MyJavaBean implements InitializingBean {  
  2.     private String desc;  
  3.     private String remark;  
  4.       
  5.     public MyJavaBean() {  
  6.         System.out.println("MyJavaBean的构造函数被执行啦");  
  7.     }  
  8.     public String getDesc() {  
  9.         return desc;  
  10.     }  
  11.     public void setDesc(String desc) {  
  12.         System.out.println("调用setDesc方法");  
  13.         this.desc = desc;  
  14.     }  
  15.     public String getRemark() {  
  16.         return remark;  
  17.     }  
  18.     public void setRemark(String remark) {  
  19.         System.out.println("调用setRemark方法");  
  20.         this.remark = remark;  
  21.     }  
  22.     public void afterPropertiesSet() throws Exception {  
  23.         System.out.println("调用afterPropertiesSet方法");  
  24.         this.desc = "在初始化方法中修改之后的描述信息";  
  25.     }  
  26.     public void initMethod() {  
  27.         System.out.println("调用initMethod方法");  
  28.     }  
  29.     public String toString() {  
  30.         StringBuilder builder = new StringBuilder();  
  31.         builder.append("[描述:").append(desc);  
  32.         builder.append(", 备注:").append(remark).append("]");  
  33.         return builder.toString();  
  34.     }  
  35. }  

 


2)定义一个BeanFactoryPostProcessor

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {  
  2.   
  3.     public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {  
  4.         System.out.println("调用MyBeanFactoryPostProcessor的postProcessBeanFactory");  
  5.         BeanDefinition bd = beanFactory.getBeanDefinition("myJavaBean");  
  6.         MutablePropertyValues pv =  bd.getPropertyValues();    
  7.         if (pv.contains("remark")) {    
  8.             pv.addPropertyValue("remark""在BeanFactoryPostProcessor中修改之后的备忘信息");    
  9.         }    
  10.     }  
  11.   
  12. }  

3)定义一个BeanPostProcessor

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public class MyBeanPostProcessor implements BeanPostProcessor {  
  2.   
  3.     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  
  4.         System.out.println("BeanPostProcessor,对象" + beanName + "调用初始化方法之前的数据: " + bean.toString());  
  5.         return bean;  
  6.     }  
  7.     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
  8.         System.out.println("BeanPostProcessor,对象" + beanName + "调用初始化方法之后的数据:" + bean.toString());  
  9.         return bean;  
  10.     }  
  11. }  

4)spring的配置

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  7.                 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
  8.                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"  
  9.     default-autowire="byName">  
  10.       
  11.     <bean id="myJavaBean" class="com.ali.caihj.postprocessor.MyJavaBean" init-method="initMethod">  
  12.         <property name="desc" value="原始的描述信息" />  
  13.         <property name="remark" value="原始的备注信息" />  
  14.     </bean>  
  15.       
  16.     <bean id="myBeanPostProcessor" class="com.ali.caihj.postprocessor.MyBeanPostProcessor" />  
  17.     <bean id="myBeanFactoryPostProcessor" class="com.ali.caihj.postprocessor.MyBeanFactoryPostProcessor" />  
  18. </beans>  

5)测试类

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public class PostProcessorMain {  
  2.     public static void main(String[] args) {  
  3.         ApplicationContext context = new ClassPathXmlApplicationContext("config/postprocessor.xml");  
  4.         MyJavaBean bean = (MyJavaBean) context.getBean("myJavaBean");  
  5.         System.out.println("===============下面输出结果============");  
  6.         System.out.println("描述:" + bean.getDesc());  
  7.         System.out.println("备注:" + bean.getRemark());  
  8.   
  9.     }  
  10. }  

6)运行结果如下:

 

7)分析

从上面的结果可以看出,BeanFactoryPostProcessor在bean实例化之前执行,之后实例化bean(调用构造函数,并调用set方法注入属性值),然后在调用两个初始化方法前后,执行了BeanPostProcessor。初始化方法的执行顺序是,先执行afterPropertiesSet,再执行init-method。

 

4、进一步深入分析

在使用ApplicationContext启动spring容器的时候,在AbstractApplicationContext.refresh()方法中,完成相关初始化工作:

1)BeanFactoryPostProcessor.postProcessBeanFactory,是在第5步执行的,invokeBeanFactoryPostProcessors方法实现如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. /** 
  2.      * Instantiate and invoke all registered BeanFactoryPostProcessor beans, 
  3.      * respecting explicit order if given. 
  4.      * <p>Must be called before singleton instantiation. 
  5.      */  
  6.     protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {  
  7.         // Invoke factory processors registered with the context instance.  
  8.         for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {  
  9.             BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();  
  10.             factoryProcessor.postProcessBeanFactory(beanFactory);  
  11.         }  
  12.   
  13.         // Do not initialize FactoryBeans here: We need to leave all regular beans  
  14.         // uninitialized to let the bean factory post-processors apply to them!  
  15.         String[] postProcessorNames =  
  16.                 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.classtruefalse);  
  17.   
  18.         // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,  
  19.         // Ordered, and the rest.  
  20.         List priorityOrderedPostProcessors = new ArrayList();  
  21.         List orderedPostProcessorNames = new ArrayList();  
  22.         List nonOrderedPostProcessorNames = new ArrayList();  
  23.         for (int i = 0; i < postProcessorNames.length; i++) {  
  24.             if (isTypeMatch(postProcessorNames[i], PriorityOrdered.class)) {  
  25.                 priorityOrderedPostProcessors.add(beanFactory.getBean(postProcessorNames[i]));  
  26.             }  
  27.             else if (isTypeMatch(postProcessorNames[i], Ordered.class)) {  
  28.                 orderedPostProcessorNames.add(postProcessorNames[i]);  
  29.             }  
  30.             else {  
  31.                 nonOrderedPostProcessorNames.add(postProcessorNames[i]);  
  32.             }  
  33.         }  
  34.   
  35.         // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.  
  36.         Collections.sort(priorityOrderedPostProcessors, new OrderComparator());  
  37.         invokeBeanFactoryPostProcessors(beanFactory, priorityOrderedPostProcessors);  
  38.   
  39.         // Next, invoke the BeanFactoryPostProcessors that implement Ordered.  
  40.         List orderedPostProcessors = new ArrayList();  
  41.         for (Iterator it = orderedPostProcessorNames.iterator(); it.hasNext();) {  
  42.             String postProcessorName = (String) it.next();  
  43.             orderedPostProcessors.add(getBean(postProcessorName));  
  44.         }  
  45.         Collections.sort(orderedPostProcessors, new OrderComparator());  
  46.         invokeBeanFactoryPostProcessors(beanFactory, orderedPostProcessors);  
  47.   
  48.         // Finally, invoke all other BeanFactoryPostProcessors.  
  49.         List nonOrderedPostProcessors = new ArrayList();  
  50.         for (Iterator it = nonOrderedPostProcessorNames.iterator(); it.hasNext();) {  
  51.             String postProcessorName = (String) it.next();  
  52.             nonOrderedPostProcessors.add(getBean(postProcessorName));  
  53.         }  
  54.         invokeBeanFactoryPostProcessors(beanFactory, nonOrderedPostProcessors);  
  55.     }  
  56.   
  57.     /** 
  58.      * Invoke the given BeanFactoryPostProcessor beans. 
  59.      */  
  60.     private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List postProcessors) {  
  61.         for (Iterator it = postProcessors.iterator(); it.hasNext();) {  
  62.             BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor) it.next();  
  63.             postProcessor.postProcessBeanFactory(beanFactory);  
  64.         }  
  65.     }  

通过beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false),获取spring配置文件中定义的所有实现BeanFactoryPostProcessor接口的bean,然后根据优先级进行排序,之后对于每个BeanFactoryPostProcessor,调用postProcessBeanFactory方法。

 

2)而BeanPostProcessor的执行,取决于配置文件中bean的定义,如果定义的bean是singleton并且不是抽象类,也不延迟初始化,则BeanPostProcessor是在第11步中执行;而对于prototype的bean,BeanPostProcessor是在程序getBean的时候执行的。在第6步中,调用registerBeanPostProcessors方法,注册所有实现BeanPostProcessor接口的bean,该方法的实现如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {  
  2.         String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.classtruefalse);  
  3.   
  4.         // Register BeanPostProcessorChecker that logs an info message when  
  5.         // a bean is created during BeanPostProcessor instantiation, i.e. when  
  6.         // a bean is not eligible for getting processed by all BeanPostProcessors.  
  7.         int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;  
  8.         beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));  
  9.   
  10.         // Separate between BeanPostProcessors that implement PriorityOrdered,  
  11.         // Ordered, and the rest.  
  12.         List priorityOrderedPostProcessors = new ArrayList();  
  13.         List orderedPostProcessorNames = new ArrayList();  
  14.         List nonOrderedPostProcessorNames = new ArrayList();  
  15.         for (int i = 0; i < postProcessorNames.length; i++) {  
  16.             if (isTypeMatch(postProcessorNames[i], PriorityOrdered.class)) {  
  17.                 priorityOrderedPostProcessors.add(beanFactory.getBean(postProcessorNames[i]));  
  18.             }  
  19.             else if (isTypeMatch(postProcessorNames[i], Ordered.class)) {  
  20.                 orderedPostProcessorNames.add(postProcessorNames[i]);  
  21.             }  
  22.             else {  
  23.                 nonOrderedPostProcessorNames.add(postProcessorNames[i]);  
  24.             }  
  25.         }  
  26.   
  27.         // First, register the BeanPostProcessors that implement PriorityOrdered.  
  28.         Collections.sort(priorityOrderedPostProcessors, new OrderComparator());  
  29.         registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);  
  30.   
  31.         // Next, register the BeanPostProcessors that implement Ordered.  
  32.         List orderedPostProcessors = new ArrayList();  
  33.         for (Iterator it = orderedPostProcessorNames.iterator(); it.hasNext();) {  
  34.             String postProcessorName = (String) it.next();  
  35.             orderedPostProcessors.add(getBean(postProcessorName));  
  36.         }  
  37.         Collections.sort(orderedPostProcessors, new OrderComparator());  
  38.         registerBeanPostProcessors(beanFactory, orderedPostProcessors);  
  39.   
  40.         // Finally, register all other BeanPostProcessors.  
  41.         List nonOrderedPostProcessors = new ArrayList();  
  42.         for (Iterator it = nonOrderedPostProcessorNames.iterator(); it.hasNext();) {  
  43.             String postProcessorName = (String) it.next();  
  44.             nonOrderedPostProcessors.add(getBean(postProcessorName));  
  45.         }  
  46.         registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);  
  47.     }  

 

在第11步中,调用finishBeanFactoryInitialization方法,该方法通过调用DefaultListableBeanFactory.preInstantiateSingletons(),进行相关初始化工作:

从上面的代码可以看出,对于非抽象类、非延迟初始化的单例bean,在spring容器启动的时候调用getBean方法来实例化bean,并进行相关初始化工作,getBean方法最终调用AbstractAutowireCapableBeanFactory.doCreateBean方法,该方法的实现如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {  
  2.         // Instantiate the bean.  
  3.         BeanWrapper instanceWrapper = null;  
  4.         if (mbd.isSingleton()) {  
  5.             instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);  
  6.         }  
  7.         if (instanceWrapper == null) {  
  8.             instanceWrapper = createBeanInstance(beanName, mbd, args);  
  9.         }  
  10.         final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);  
  11.         Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);  
  12.   
  13.         // Allow post-processors to modify the merged bean definition.  
  14.         synchronized (mbd.postProcessingLock) {  
  15.             if (!mbd.postProcessed) {  
  16.                 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);  
  17.                 mbd.postProcessed = true;  
  18.             }  
  19.         }  
  20.   
  21.         // Eagerly cache singletons to be able to resolve circular references  
  22.         // even when triggered by lifecycle interfaces like BeanFactoryAware.  
  23.         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&  
  24.                 isSingletonCurrentlyInCreation(beanName));  
  25.         if (earlySingletonExposure) {  
  26.             if (logger.isDebugEnabled()) {  
  27.                 logger.debug("Eagerly caching bean '" + beanName +  
  28.                         "' to allow for resolving potential circular references");  
  29.             }  
  30.             addSingletonFactory(beanName, new ObjectFactory() {  
  31.                 public Object getObject() throws BeansException {  
  32.                     return getEarlyBeanReference(beanName, mbd, bean);  
  33.                 }  
  34.             });  
  35.         }  
  36.   
  37.         // Initialize the bean instance.  
  38.         Object exposedObject = bean;  
  39.         try {  
  40.             populateBean(beanName, mbd, instanceWrapper);  
  41.             exposedObject = initializeBean(beanName, exposedObject, mbd);  
  42.         }  
  43.         catch (Throwable ex) {  
  44.             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {  
  45.                 throw (BeanCreationException) ex;  
  46.             }  
  47.             else {  
  48.                 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);  
  49.             }  
  50.         }  
  51.   
  52.         if (earlySingletonExposure) {  
  53.             Object earlySingletonReference = getSingleton(beanName, false);  
  54.             if (earlySingletonReference != null) {  
  55.                 if (exposedObject == bean) {  
  56.                     exposedObject = earlySingletonReference;  
  57.                 }  
  58.                 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {  
  59.                     String[] dependentBeans = getDependentBeans(beanName);  
  60.                     Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);  
  61.                     for (int i = 0; i < dependentBeans.length; i++) {  
  62.                         String dependentBean = dependentBeans[i];  
  63.                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {  
  64.                             actualDependentBeans.add(dependentBean);  
  65.                         }  
  66.                     }  
  67.                     if (!actualDependentBeans.isEmpty()) {  
  68.                         throw new BeanCurrentlyInCreationException(beanName,  
  69.                                 "Bean with name '" + beanName + "' has been injected into other beans [" +  
  70.                                 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +  
  71.                                 "] in its raw version as part of a circular reference, but has eventually been " +  
  72.                                 "wrapped. This means that said other beans do not use the final version of the " +  
  73.                                 "bean. This is often the result of over-eager type matching - consider using " +  
  74.                                 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");  
  75.                     }  
  76.                 }  
  77.             }  
  78.         }  
  79.   
  80.         // Register bean as disposable.  
  81.         registerDisposableBeanIfNecessary(beanName, bean, mbd);  
  82.   
  83.         return exposedObject;  
  84.     }  

在该方法中,首先调用createBeanInstance方法,创建bean实例对象(这个时候执行bean的构造方法),然后调用populateBean方法,对bean进行填充,注入相关依赖,之后再调用方法initializeBean,进行相关初始化工作,initializeBean方法的实现如下:

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {  
  2.         if (bean instanceof BeanNameAware) {  
  3.             ((BeanNameAware) bean).setBeanName(beanName);  
  4.         }  
  5.   
  6.         if (bean instanceof BeanClassLoaderAware) {  
  7.             ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());  
  8.         }  
  9.   
  10.         if (bean instanceof BeanFactoryAware) {  
  11.             ((BeanFactoryAware) bean).setBeanFactory(this);  
  12.         }  
  13.   
  14.         Object wrappedBean = bean;  
  15.         if (mbd == null || !mbd.isSynthetic()) {  
  16.             wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  
  17.         }  
  18.   
  19.         try {  
  20.             invokeInitMethods(beanName, wrappedBean, mbd);  
  21.         }  
  22.         catch (Throwable ex) {  
  23.             throw new BeanCreationException(  
  24.                     (mbd != null ? mbd.getResourceDescription() : null),  
  25.                     beanName, "Invocation of init method failed", ex);  
  26.         }  
  27.   
  28.         if (mbd == null || !mbd.isSynthetic()) {  
  29.             wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  
  30.         }  
  31.         return wrappedBean;  
  32.     }  

从上面的实现可以看出,先调用applyBeanPostProcessorsBeforeInitialization方法,执行每个BeanPostProcessor的postProcessBeforeInitialization,然后调用invokeInitMethods方法,执行bean的初始化方法,最后调用applyBeanPostProcessorsAfterInitialization方法,执行每个BeanPostProcessor的postProcessAfterInitialization方法。这三个方法的实现如下:

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1.     public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)  
  2.             throws BeansException {  
  3.   
  4.         Object result = existingBean;  
  5.         for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {  
  6.             BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();  
  7.             result = beanProcessor.postProcessBeforeInitialization(result, beanName);  
  8.         }  
  9.         return result;  
  10.     }  
  11.   
  12.     public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)  
  13.             throws BeansException {  
  14.   
  15.         Object result = existingBean;  
  16.         for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {  
  17.             BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();  
  18.             result = beanProcessor.postProcessAfterInitialization(result, beanName);  
  19.         }  
  20.         return result;  
  21.     }  
  22. protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)  
  23.             throws Throwable {  
  24.   
  25.         boolean isInitializingBean = (bean instanceof InitializingBean);  
  26.         if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {  
  27.             if (logger.isDebugEnabled()) {  
  28.                 logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");  
  29.             }  
  30.             ((InitializingBean) bean).afterPropertiesSet();  
  31.         }  
  32.   
  33.         String initMethodName = (mbd != null ? mbd.getInitMethodName() : null);  
  34.         if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&  
  35.                 !mbd.isExternallyManagedInitMethod(initMethodName)) {  
  36.             invokeCustomInitMethod(beanName, bean, initMethodName, mbd.isEnforceInitMethod());  
  37.         }  
  38.     }  

从invokeInitMethods方法的实现可以看出,先执行afterPropertiesSet方法,然后再通过反射,执行init-method指定的方法。

分享到:
评论

相关推荐

    com-spring-ioc-demo:源码主要是学习Spring IOC的原理,以及对Bean的注册及控制,主要运用以下类对Spring进行扩展学习:BeanPostProcessor,BeanFactoryAware,BeanNameAware,ApplicationContextAware,FactoryBean,BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor,BeanPostProcessor,ResourceLoaderA

    BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor,BeanPostProcessor,ResourceLoaderAware,InvocationHandler。 BeanPostProcessor接口的实现类如何被注册到Spring容器2.更改bean的定义...

    Spring BeanPostProcessor接口使用详解

    此外,Spring框架还提供了其他类型的后处理器接口,例如BeanFactoryPostProcessor和BeanValidationPostProcessor等,这些接口也可以用于实现各种Bean处理需求。 BeanPostProcessor接口是一个非常有用的工具,能够...

    Spring认证考试指南

    4. **Spring Bean生命周期**:清楚Spring Bean的生命周期,使用BeanFactoryPostProcessor和BeanPostProcessor,理解Spring代理的工作原理,掌握bean创建顺序的确定,以及避免按类型注入bean时的问题。 5. **面向切面...

    详解如何在低版本的Spring中快速实现类似自动配置的功能

    综上所述,要在低版本的Spring中实现类似自动配置的功能,需要巧妙地利用Spring提供的扩展点,如BeanFactoryPostProcessor和BeanPostProcessor,以及Java Config和XML配置的组合。同时,还需要结合生命周期回调和...

    Spring容器扩展机制的实现原理

    在使用Spring时,可以通过实现BeanFactoryPostProcessor和BeanPostProcessor接口来扩展容器的功能。例如,可以使用BeanFactoryPostProcessor接口来修改BeanDefinition的信息,或者使用BeanPostProcessor接口来修改...

    Spring源码流程图

    在Spring框架中,核心组件包括BeanFactory、BeanDefinitionReader、BeanFactoryPostProcessor、BeanPostProcessor等。这些组件协作以实现Bean的创建、初始化和生命周期管理。 Bean定义信息 Bean定义信息是描述Bean...

    Spring源码学习四:BeanDefinition装载前奏曲1

    同时,理解BeanFactoryPostProcessor和BeanPostProcessor的作用,以及它们如何扩展Spring的功能,是深入理解Spring框架的关键。对于一些辅助性的代码,如XML解析和验证,可以在掌握了核心概念后再进行深入研究。

    2023最新Spring全家桶面试题-图灵徐庶

    11. Spring的扩展点:包括BeanFactoryPostProcessor、BeanPostProcessor、InstantiationAwareBeanPostProcessor等。 二、Spring Beans 12. Spring beans:是Spring框架中的核心组件,提供了一个通用的方式来创建和...

    spring-framework-4.3.6 API

    1. 容器扩展:Spring 提供了 BeanPostProcessor 和 BeanFactoryPostProcessor 接口,允许用户自定义扩展点,实现更精细的控制。 2. Annotation-based Configuration:除了 XML 配置外,4.3.6 版本更加强调注解驱动的...

    SPRING技术内幕_深入解析SPRING架构与设计原理

    开发者可以自定义AOP的切面,通过实现BeanPostProcessor和BeanFactoryPostProcessor来自定义Bean的创建过程。另外,Spring允许开发者通过XML或者注解来配置Spring容器。 知识点七:Spring框架与其他技术的整合 ...

    Spring4中文文档

    文档最后还涉及到了Spring容器的扩展点,如BeanPostProcessor和BeanFactoryPostProcessor,这些扩展点让开发者有机会在Spring容器实例化Bean前后以及加载配置元数据前后执行自定义逻辑。 整体来看,Spring4中文文档...

    Spring源码分析.docx

    在 Spring 框架中,Bean 对象的创建过程是一个复杂的过程,涉及到多个步骤和接口。下面将对 Spring 源码中 Bean 对象的创建过程进行分析和解释。 1. 创建工厂,到达 BeanDefinition 步骤 在 Spring 框架中,Bean ...

    spring-framework-3.2.13.RELEASE 源码

    最后,Spring的容器提供了多种扩展点,如BeanPostProcessor、BeanFactoryPostProcessor等,这使得开发者可以在容器初始化阶段自定义逻辑。在3.2.13.RELEASE中,我们可以探索这些扩展点的实现,以及如何利用它们增强...

    Spring-Reference_zh_CN(Spring中文参考手册)

    6.1.2. Spring AOP的功能和目标 6.1.3. Spring的AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点(pointcut) 6.2.3.1. 切入点指定者的支持 6.2.3.2. 合并切入点...

    java学习之spring2.0

    - **Bean的高级功能**:如bean的继承、FactoryBean、BeanPostProcessor和BeanFactoryPostProcessor等,增强了Bean的灵活性和扩展性。 4. **整合其他技术** - **MVC框架**:Spring MVC提供了模型-视图-控制器的...

    从Dubbo启动看Dubbo和Spring的关系1

    总的来说,Dubbo和Spring的关系体现在Spring作为基础框架,提供了加载和管理配置的能力,而Dubbo利用Spring的这些能力,通过`BeanFactoryPostProcessor`等机制,在Spring环境中注入自己的服务治理逻辑。这种组合使得...

    spring中注解的实现原理

    通过实现`BeanFactoryPostProcessor`或`BeanPostProcessor`接口,你可以扩展Spring的行为,使其在处理自定义注解时执行特定的操作。 总结来说,Spring中注解的实现原理涉及到元注解的定义、注解处理器的运行、Bean...

Global site tag (gtag.js) - Google Analytics