2016-02-16 22 views
0

根據Spring框架的JavaDoc中,BeanPostProcessor是:構造函數DI如何使用AutowiredAnnotationBeanPostProcessor工作?

廠掛鉤,通過preInstantiateSingletons允許新的bean實例的定製修改

春天在什麼實例化的非懶單豆類使用反射和那麼AutowiredAnnotationBeanPostProcessor後來使用反射來設置在構造函數(和setter/fields)上定義了@Autowired的字段(如final字段)?

如果是這樣,是否可以編寫自定義BeanPostProcessor,在AutowiredAnnotationBeanPostProcessor之前處理以驗證此行爲?我試圖通過實施PriorityOrdered如下使用自定義BeanPostProcessor這樣做:

@Override 
public int getOrder() { 
    return Ordered.LOWEST_PRECEDENCE; 
} 

注:然而,當postProcessBeforeInitialization叫,豆類似乎已經通過@Autowired設置字段。

回答

1

看裏面AbstractAutowireCapableBeanFactory.doCreateBean。 基本上有三個步驟。

  1. createBeanInstance構建bean對象
  2. populateBean自動裝配bean的屬性值
  3. initializeBean火的BeanPostProcessor

所以的BeanPostProcessor太late.but往裏populateBean,您會發現InstantiationAwareBeanPostProcessor將在autowired屬性之前執行。 所以你可以爲你創建bean類型InstantiationAwareBeanPostProcessor

完整的例子

@Configuration 
public class DIBeforeAutowired { 

    public static void main(String[] args) { 
     AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(); 
     annotationConfigApplicationContext.register(DIBeforeAutowired.class); 
     annotationConfigApplicationContext.refresh(); 
     InjectClass injectClass = annotationConfigApplicationContext.getBean(InjectClass.class); 
     injectClass.print(); 
    } 

    @Component 
    public static class InstantiationAwareBeanPostProcessorTest extends AutowiredAnnotationBeanPostProcessor { 

     public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { 
      if (bean instanceof InjectClass) { 
       System.out.println(((InjectClass) bean).getInjectField()); 
      } 
      return true; 
     } 

     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
      if (bean instanceof InjectClass) { 
       System.out.println(((InjectClass) bean).getInjectField()); 
      } 
      return bean; 
     } 

     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
      if (bean instanceof InjectClass) { 
       System.out.println(((InjectClass) bean).getInjectField()); 
      } 
      return bean; 
     } 
    } 

    @Component 
    public static class InjectField { 
     public String getHelloWorld() { 
      return "hello world"; 
     } 
    } 

    @Component 
    public static class InjectClass { 

     @Autowired 
     InjectField injectField; 

     public void print() { 
      System.out.println(injectField.getHelloWorld()); 
     } 

     public InjectField getInjectField() { 
      return injectField; 
     } 

    } 

}