1. 程式人生 > >4、Spring原始碼分析4之初始化Bean

4、Spring原始碼分析4之初始化Bean

1、記錄建立bean的ObjectFactory,目的是為了解決迴圈依賴

if (instanceWrapper == null) {
   //上一篇bean的載入後部分主要分析了bean的建立,此步驟完成之後bean已經建立完成,但屬性還沒有賦值,Spring
   //解決迴圈依賴的關鍵步驟就在此步驟完成之後,bean已建立但還沒有屬性賦值,如下圖
   instanceWrapper = createBeanInstance(beanName, mbd, args);
}
如下圖,以最簡單的AB迴圈依賴為例,A中有屬性類B,B中又有屬性類A,那麼初始化beanA的過程如下圖.

//上圖中addSingletonFactory邏輯,只有是單例的,允許迴圈依賴且該bean正在建立中(建立時會記錄該屬性,建立完成會移除該屬性),
//只有三個條件都滿足才會addSingletonFactory
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences
                                                    && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
   //為避免後期迴圈依賴,可以在bean初始化後屬性賦值之前將建立例項的ObjectFactory加入工廠
   addSingletonFactory(beanName, new ObjectFactory<Object>() {
      public Object getObject() throws BeansException {
         return getEarlyBeanReference(beanName, mbd, bean);
      }
   });
}
protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
   Assert.notNull(singletonFactory, "Singleton factory must not be null");
   synchronized (this.singletonObjects) {
      if (!this.singletonObjects.containsKey(beanName)) {
         //放入map中
         this.singletonFactories.put(beanName, singletonFactory);
         //目的是檢測迴圈引用,移除
         this.earlySingletonObjects.remove(beanName);
         this.registeredSingletons.add(beanName);
      }
   }
}
//我們熟知的AOP就是在這裡將advice動態織如bean中,若沒有則直接返回bean
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
   Object exposedObject = bean;
   if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
            if (exposedObject == null) {
               return exposedObject;
            }
         }
      }
   }
   return exposedObject;
}

2、屬性注入

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
   BeanWrapper instanceWrapper = null;
 
   if (instanceWrapper == null) {
   //1.建立bean,但還沒有屬性賦值
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   //2.條件滿足的話講ObjectFactory放入map中,為了解決迴圈依賴
   addSingletonFactory(beanName, new ObjectFactory<Object>() {
         public Object getObject() throws BeansException {
            return getEarlyBeanReference(beanName, mbd, bean);
         }
   });
   
   Object exposedObject = bean;
   try {
      //3.屬性賦值
      populateBean(beanName, mbd, instanceWrapper);
      if (exposedObject != null) {
      //4.呼叫一系列初始化方法
         exposedObject = initializeBean(beanName, exposedObject, mbd);
      }
   }

   return exposedObject;
}
//之前已經分析了步驟1建立bean和步驟2新增ObjectFactory,現在來分析屬性賦值populateBean。
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
   //讀取配置檔案,解析標籤之後,此處的pvs已經有值了,就是配置檔案中配置的lwh sayHello
   PropertyValues pvs = mbd.getPropertyValues();

   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

      //根據名稱自動注入
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }
      
      //根據型別自動注入
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }

      pvs = newPvs;
   }
   
   //屬性賦值
   applyPropertyValues(beanName, mbd, bw, pvs);
}

protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

   //尋找bw中需要依賴注入的屬性,若是配置檔案中配置了person屬性,則此處查出來的propertyNames為空
   //因為配置檔案中配置了name為person的bean,此處查找出來的propertyNames封裝的就是person,若是將配置文
   //件中autowire改為byType程式也可以正常執行;若將配置的person的id改為其他的,則byName不能正常執行,而
   //byType可以正常執行
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      if (containsBean(propertyName)) {
         //遞迴初始化相關的bean,此處為person
         Object bean = getBean(propertyName);
         //加到pvs屬性中
         pvs.add(propertyName, bean);
         registerDependentBean(propertyName, beanName);
      }
   }
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {

   MutablePropertyValues mpvs = null;
   List<PropertyValue> original;

   if (pvs instanceof MutablePropertyValues) {
      mpvs = (MutablePropertyValues) pvs;
      if (mpvs.isConverted()) {
         try {
            bw.setPropertyValues(mpvs);
            return;
         }
      }
      original = mpvs.getPropertyValueList();
   }
   else {
      original = Arrays.asList(pvs.getPropertyValues());
   }
   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) {
      converter = bw;
   }
   BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

   List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
   boolean resolveNecessary = false;
   for (PropertyValue pv : original) {
      if (pv.isConverted()) {
         deepCopy.add(pv);
      }
      else {
         String propertyName = pv.getName();
         Object originalValue = pv.getValue();
         Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
         Object convertedValue = resolvedValue;
         boolean convertible = bw.isWritableProperty(propertyName) &&
               !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
         if (convertible) {
            convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
         }
        
         if (resolvedValue == originalValue) {
            if (convertible) {
               pv.setConvertedValue(convertedValue);
            }
            deepCopy.add(pv);
         }
         else if (convertible && originalValue instanceof TypedStringValue &&
               !((TypedStringValue) originalValue).isDynamic() &&
               !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
            pv.setConvertedValue(convertedValue);
            deepCopy.add(pv);
         }
         else {
            resolveNecessary = true;
            deepCopy.add(new PropertyValue(pv, convertedValue));
         }
      }
   }
   if (mpvs != null && !resolveNecessary) {
      mpvs.setConverted();
   }
   try {
      //賦值核心程式碼,此步驟完成之後,bean中的屬性就被賦值了
      bw.setPropertyValues(new MutablePropertyValues(deepCopy));
   }
}

3、呼叫一系列初始化方法

//分析完了屬性賦值populateBean方法,然後分析一系列初始化方法
//屬性賦值
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
   //呼叫初始化方法
   exposedObject = initializeBean(beanName, exposedObject, mbd);
}

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    //1.啟用Aware方法
   invokeAwareMethods(beanName, bean);

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      //2.執行BeanPostProcessor的before方法
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }
   try {
      //3.啟用使用者定義的初始化方法,包括介面InitializingBean中的初始化方法和使用者配置的init-method
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   if (mbd == null || !mbd.isSynthetic()) {
      //4.執行BeanPostProcessor的after方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}
步驟1:啟用Aware方法
private void invokeAwareMethods(final String beanName, final Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
      }
      if (bean instanceof BeanFactoryAware) {
         //附錄1中的類實現了BeanFactoryAware介面,因此會呼叫該方法,輸出注入容器BeanFactroy
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}
步驟2:執行BeanPostProcessor的before方法
ConfigurableBeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactory.xml"));
//BeanFactory要手動註冊BeanPostProcessor,而ApplicationContext會手動檢測
bf.addBeanPostProcessor(new MyTestBean());
bf.getBean("myTestBean", MyTestBean.class);
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName){

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      //呼叫這邊會輸出我是MyTestBean的postProcessBeforeInitialization方法
      result = beanProcessor.postProcessBeforeInitialization(result, beanName);
      if (result == null) {
         return result;
      }
   }
   return result;
}
步驟3:啟用使用者的初始化方法
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd){

   boolean isInitializingBean = (bean instanceof InitializingBean);
   //刪去了部分程式碼
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
       //呼叫InitializingBean介面中定義的初始化方法
      ((InitializingBean) bean).afterPropertiesSet();
   }
   if (mbd != null) {
      //配置檔案init-method中配置的初始化方法
      String initMethodName = mbd.getInitMethodName();
      if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         //底層使用反射呼叫初始化方法
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}
步驟4:執行BeanPostProcessor的after方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName){

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      result = beanProcessor.postProcessAfterInitialization(result, beanName);
      if (result == null) {
         return result;
      }
   }
   return result;
}
附錄
1、根據名稱注入例子
public class MyTestBean implements BeanFactoryAware, BeanPostProcessor, InitializingBean, 
                                                                        DestructionAwareBeanPostProcessor{

    private BeanFactory beanFactory;

    private Person person;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    private String testStr = "xbx";

    public String getTestStr() {
        return testStr;
    }

    public void setTestStr(String testStr) {
        this.testStr = testStr;
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("注入容器BeanFactory");
        this.beanFactory = beanFactory;
    }

    public void init(){
        System.out.println("我是MyTestBean的初始化方法");
    }

    public void destroy(){
        System.out.println("我是MyTestBean的銷燬方法");
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName){
        System.out.println("我是MyTestBean的postProcessBeforeInitialization方法");
        return null;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName){
        System.out.println("我是MyTestBean的postProcessAfterInitialization方法");
        return null;
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("我是MyTestBean的自定義的初始化方法");
    }

    public void postProcessBeforeDestruction(Object bean, String beanName){
        System.out.println("我是MyTestBean的自定義的銷燬方法");
    }
}
//配置檔案中只配置了testStr屬性,並沒有配置person屬性
<bean id="myTestBean" class="com.lwh.spring.bean.MyTestBean"
      autowire="byName" init-method="init" destroy-method="destroy">
    <property name="testStr" value="lwh sayHello"/>
</bean>

<bean id="person" class="com.lwh.spring.bean.Person