【spring源碼分析】IOC容器初始化(十一)

前言:前面分析了doCreateBean中的createBeanInstance函數,接下來分析其剩餘流程。java


首先貼上doCreateBean函數:算法

  1 // AbstractAutowireCapableBeanFactory
  2 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
  3             throws BeanCreationException {
  4 
  5         // Instantiate the bean.
  6         // BeanWrapper是對Bean的包裝,其接口中所定義的功能很簡單包括設置獲取被包裝的對象、獲取被包裝bean的屬性描述器
  7         BeanWrapper instanceWrapper = null;
  8         // 若是是單例模型,則從未完成的FactoryBean緩存中刪除
  9         if (mbd.isSingleton()) {
 10             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
 11         }
 12         // 使用合適的實例化策略來建立新的實例:工廠方法、構造函數自動注入、簡單初始化
 13         if (instanceWrapper == null) {
 14             instanceWrapper = createBeanInstance(beanName, mbd, args);
 15         }
 16         // 包裝的對象實例
 17         final Object bean = instanceWrapper.getWrappedInstance();
 18         // 包裝的實例對象的類型
 19         Class<?> beanType = instanceWrapper.getWrappedClass();
 20         if (beanType != NullBean.class) {
 21             mbd.resolvedTargetType = beanType;
 22         }
 23 
 24         // Allow post-processors to modify the merged bean definition.
 25         // 先作同步,而後判斷是否有後置處理
 26         synchronized (mbd.postProcessingLock) {
 27             if (!mbd.postProcessed) {
 28                 try {
 29                     // 後置處理修改BeanDefinition
 30                     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 31                 } catch (Throwable ex) {
 32                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 33                                                     "Post-processing of merged bean definition failed", ex);
 34                 }
 35                 mbd.postProcessed = true;
 36             }
 37         }
 38 
 39         // Eagerly cache singletons to be able to resolve circular references
 40         // even when triggered by lifecycle interfaces like BeanFactoryAware.
 41         // 解決單例模式的循環依賴         // 單例模式               運行循環依賴
 42         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
 43                 isSingletonCurrentlyInCreation(beanName));// 當前單例bean是否正在被建立
 44         if (earlySingletonExposure) {
 45             if (logger.isDebugEnabled()) {
 46                 logger.debug("Eagerly caching bean '" + beanName +
 47                                      "' to allow for resolving potential circular references");
 48             }
 49             // 提早將建立的bean實例加入到singletonFactories中
 50             // 爲了後期避免循環依賴
 51             addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
 52         }
 53 
 54         // Initialize the bean instance.
 55         // 開始初始化bean實例對象
 56         Object exposedObject = bean;
 57         try {
 58             // 對bean進行填充,主要是進行屬性注入,其中,可能存在依賴於其餘bean的屬性,則會遞歸初始化依賴bean
 59             populateBean(beanName, mbd, instanceWrapper);
 60             // 進行bean初始化
 61             exposedObject = initializeBean(beanName, exposedObject, mbd);
 62         } catch (Throwable ex) {
 63             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
 64                 throw (BeanCreationException) ex;
 65             } else {
 66                 throw new BeanCreationException(
 67                         mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
 68             }
 69         }
 70 
 71         // 循環依賴處理
 72         if (earlySingletonExposure) {
 73             // 獲取earlySingletonReference
 74             Object earlySingletonReference = getSingleton(beanName, false);
 75             // 只有在循環依賴的狀況下,earlySingletonReference纔不會爲null
 76             if (earlySingletonReference != null) {
 77                 // 若是exposedObject沒有在初始化方法中改變,也就是沒有被加強
 78                 if (exposedObject == bean) {
 79                     exposedObject = earlySingletonReference;
 80                 } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { // 處理依賴
 81                     String[] dependentBeans = getDependentBeans(beanName);
 82                     Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
 83                     for (String dependentBean : dependentBeans) {
 84                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
 85                             actualDependentBeans.add(dependentBean);
 86                         }
 87                     }
 88                     if (!actualDependentBeans.isEmpty()) {
 89                         throw new BeanCurrentlyInCreationException(beanName,
 90                                                                    "Bean with name '" + beanName + "' has been injected into other beans [" +
 91                                                                            StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
 92                                                                            "] in its raw version as part of a circular reference, but has eventually been " +
 93                                                                            "wrapped. This means that said other beans do not use the final version of the " +
 94                                                                            "bean. This is often the result of over-eager type matching - consider using " +
 95                                                                            "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
 96                     }
 97                 }
 98             }
 99         }
100 
101         // Register bean as disposable.
102         try {
103             // 註冊bean
104             registerDisposableBeanIfNecessary(beanName, bean, mbd);
105         } catch (BeanDefinitionValidationException ex) {
106             throw new BeanCreationException(
107                     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
108         }
109 
110         return exposedObject;
111     }

分析:數組

  • 首先判斷是否有後置處理器,若是存在在先執行後置處理器(applyMergedBeanDefinitionPostProcessors)。
  • 接下來是爲處理循環依賴作前期準備,這部分後面會單獨進行分析。
  • 開始初始化bean對象,首先對bean進行填充,而後進行初始化。
  • 處理循環依賴。
  • 註冊bean對象。

AbstractAutowireCapableBeanFactory#populateBean

  1 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  2         // 沒有實例化對象
  3         if (bw == null) {
  4             // 有屬性,則拋出異常
  5             if (mbd.hasPropertyValues()) {
  6                 throw new BeanCreationException(
  7                         mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
  8             } else {
  9                 // 沒有屬性,則直接返回
 10                 // Skip property population phase for null instance.
 11                 return;
 12             }
 13         }
 14 
 15         // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
 16         // state of the bean before properties are set. This can be used, for example,
 17         // to support styles of field injection.
 18         // 在設置屬性以前給InstantiationAwareBeanPostProcessors最後一次改變bean的機會
 19         boolean continueWithPropertyPopulation = true;
 20 
 21         // bean不是合成的,即未由應用程序自己定義
 22         // 是否持有InstantiationAwareBeanPostProcessors
 23         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
 24             // 迭代全部的BeanPostProcessor
 25             for (BeanPostProcessor bp : getBeanPostProcessors()) {
 26                 // 若是爲InstantiationAwareBeanPostProcessors
 27                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
 28                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
 29                     // 返回值爲是否繼續填充bean
 30                     // postProcessAfterInstantiation:若是應該在bean上面設置屬性,則返回true,不然返回false
 31                     // 通常狀況下,應該返回true
 32                     // 返回false的話,將會阻止此bean實例上調用任何後續的InstantiationAwareBeanPostProcessors實例
 33                     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
 34                         continueWithPropertyPopulation = false;
 35                         break;
 36                     }
 37                 }
 38             }
 39         }
 40 
 41         // 若是後續處理器發出中止填充命令,則終止後續操做
 42         if (!continueWithPropertyPopulation) {
 43             return;
 44         }
 45 
 46         // bean的屬性值
 47         PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
 48 
 49         // 自動注入
 50         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
 51                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
 52             // 將PropertyValues封裝成MutablePropertyValues對象
 53             // MutablePropertyValues對象對屬性進行簡單的操做,並提供構造函數以支持Map的深度複製和構造
 54             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
 55 
 56             // 根據屬性名稱自動注入
 57             // Add property values based on autowire by name if applicable.
 58             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
 59                 autowireByName(beanName, mbd, bw, newPvs);
 60             }
 61 
 62             // 根據屬性類型自動注入
 63             // Add property values based on autowire by type if applicable.
 64             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
 65                 autowireByType(beanName, mbd, bw, newPvs);
 66             }
 67 
 68             pvs = newPvs;
 69         }
 70 
 71         // 是否已經註冊了InstantiationAwareBeanPostProcessors
 72         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
 73         // 是否須要進行依賴檢查
 74         boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
 75 
 76         // BeanPostProcessor處理
 77         if (hasInstAwareBpps || needsDepCheck) {
 78             if (pvs == null) {
 79                 pvs = mbd.getPropertyValues();
 80             }
 81             // 從BeanWrapper中提取PropertyDescriptor結果集
 82             PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
 83             if (hasInstAwareBpps) {
 84                 for (BeanPostProcessor bp : getBeanPostProcessors()) {
 85                     if (bp instanceof InstantiationAwareBeanPostProcessor) {
 86                         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
 87                         pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
 88                         if (pvs == null) {
 89                             return;
 90                         }
 91                     }
 92                 }
 93             }
 94             // 依賴檢查
 95             if (needsDepCheck) {
 96                 checkDependencies(beanName, mbd, filteredPds, pvs);
 97             }
 98         }
 99 
100         // 將屬性引用到bean中
101         if (pvs != null) {
102             applyPropertyValues(beanName, mbd, bw, pvs);
103         }
104     }

分析:緩存

該函數的主要做用是將BeanDefinition中的屬性值賦值給BeanWrapper對象。安全

  • 若是BeanWrapper爲null,而且有屬性值,則拋出異常,不然直接返回。
  • 若是存在PostProcessor,則在這裏給其最後一次改變bean的機會。
  • 若是在後置處理器組織bean實例繼續初始化,則直接返回。
  • 獲取bean的PropertyValues屬性,根據不一樣狀況進行屬性注入:根據屬性名稱或根據屬性類型。
  • 再次進行後置處理,這裏主要對屬性值進行操做。
  • 進行依賴檢查。
  • 調用applyPropertyValues方法將屬性填充到BeanWrapper中。

自動注入

Spring會根據注入類型(byName/byType)的不一樣,調用不一樣的方法來注入屬性值。app

AbstractAutowireCapableBeanFactory#autowireByNameide

 1 protected void autowireByName(
 2             String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
 3         // 獲取bean對象中的非簡單屬性
 4         // 非簡單屬性:類型爲對象類型的屬性,但這裏並非將全部的對象類型都會找到,好比8個原始類型,String類型、Number類型、Date類型等會被忽略
 5         String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
 6         // 遍歷propertyName數組
 7         for (String propertyName : propertyNames) {
 8             // 若是容器中包含指定名稱的bean,則將該bean注入到bean中
 9             if (containsBean(propertyName)) {
10                 // 初始化相關bean
11                 Object bean = getBean(propertyName);
12                 // 爲指定名稱的屬性賦值
13                 pvs.add(propertyName, bean);
14                 // 屬性依賴注入
15                 registerDependentBean(propertyName, beanName);
16                 if (logger.isDebugEnabled()) {
17                     logger.debug("Added autowiring by name from bean name '" + beanName +
18                                          "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
19                 }
20             } else {
21                 if (logger.isTraceEnabled()) {
22                     logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
23                                          "' by name: no matching bean found");
24                 }
25             }
26         }
27     }

分析:函數

該函數爲根據屬性名稱完成自動依賴注入。post

  • 首先獲取bean對象的非簡單屬性。非簡單屬性:類型爲對象類型的屬性,但並非將全部的對象類型都會找到,好比8個原始類型:String、Number等類型都會被忽略。
  • 循環遍歷屬性名,而後爲指定名稱的屬性賦值。
  • 而後進行屬性依賴注入。

AbstractAutowireCapableBeanFactory#unsatisfiedNonSimplePropertiesui

 1 protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
 2         // 建立結果集
 3         Set<String> result = new TreeSet<>();
 4         PropertyValues pvs = mbd.getPropertyValues();
 5         // 遍歷PropertyDescriptor數組
 6         PropertyDescriptor[] pds = bw.getPropertyDescriptors();
 7         for (PropertyDescriptor pd : pds) {
 8             if (pd.getWriteMethod() != null // 有可寫方法
 9                     && !isExcludedFromDependencyCheck(pd) // 依賴檢測中沒有被忽略
10                     && !pvs.contains(pd.getName()) // pvs中不包含該屬性名
11                     && !BeanUtils.isSimpleProperty(pd.getPropertyType())) { // 不是簡單屬性類型
12                 result.add(pd.getName()); // 添加到result集合中
13             }
14         }
15         return StringUtils.toStringArray(result);
16     }

分析:

過濾條件:有可寫方法、依賴檢測中沒有被忽略、pvs中不包含該屬性名、不爲簡單類型。

過濾結果:獲取須要依賴注入的屬性。

BeanUtils#isSimpleValueType

1     public static boolean isSimpleValueType(Class<?> clazz) {
2         return (ClassUtils.isPrimitiveOrWrapper(clazz) ||
3                 Enum.class.isAssignableFrom(clazz) ||
4                 CharSequence.class.isAssignableFrom(clazz) ||
5                 Number.class.isAssignableFrom(clazz) ||
6                 Date.class.isAssignableFrom(clazz) ||
7                 URI.class == clazz || URL.class == clazz ||
8                 Locale.class == clazz || Class.class == clazz);
9     }

分析:

該方法就是獲取簡單類型的對象。

MutablePropertyValues#add

 1    /**
 2      * 存儲屬性對象  PropertyValue:name->value
 3      */
 4 private final List<PropertyValue> propertyValueList;
 5 
 6 public MutablePropertyValues add(String propertyName, @Nullable Object propertyValue) {
 7         addPropertyValue(new PropertyValue(propertyName, propertyValue));
 8         return this;
 9     }
10 
11 public MutablePropertyValues addPropertyValue(PropertyValue pv) {
12         for (int i = 0; i < this.propertyValueList.size(); i++) {
13             PropertyValue currentPv = this.propertyValueList.get(i);
14             if (currentPv.getName().equals(pv.getName())) {
15                 pv = mergeIfRequired(pv, currentPv);
16                 setPropertyValueAt(pv, i);
17                 return this;
18             }
19         }
20         this.propertyValueList.add(pv);
21         return this;
22     }

分析:

屬性注入邏輯簡單,就是經過propertyName進行對比,從這裏也能夠發現,若是存在相同的屬性名會發生覆蓋的狀況,以最後的屬性爲主。

AbstractAutowireCapableBeanFactory#autowireByType

 1 protected void autowireByType(
 2             String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
 3 
 4         // 獲取TypeConverter實例
 5         // 使用自定義的TypeConverter,用於取代默認的PropertyEditor機制
 6         TypeConverter converter = getCustomTypeConverter();
 7         if (converter == null) {
 8             converter = bw;
 9         }
10 
11         Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
12         // 獲取非簡單屬性
13         String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
14         for (String propertyName : propertyNames) {
15             try {
16                 // 獲取PropertyDescriptor實例
17                 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
18                 // Don't try autowiring by type for type Object: never makes sense,
19                 // even if it technically is a unsatisfied, non-simple property.
20                 // 不要嘗試按類型
21                 if (Object.class != pd.getPropertyType()) {
22                     // 探測指定屬性的set方法
23                     MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
24                     // Do not allow eager init for type matching in case of a prioritized post-processor.
25                     boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
26                     DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
27                     // 解析指定beanName的屬性所匹配的值,並把解析到的屬性名稱存儲在autowiredBeanNames中
28 
29                     // 當屬性存在封裝的bean時,會找到全部匹配的bean並將其注入
30                     Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
31                     if (autowiredArgument != null) {
32                         pvs.add(propertyName, autowiredArgument);
33                     }
34                     // 遍歷autowiredBeanNames數組
35                     for (String autowiredBeanName : autowiredBeanNames) {
36                         // 屬性依賴注入
37                         registerDependentBean(autowiredBeanName, beanName);
38                         if (logger.isDebugEnabled()) {
39                             logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
40                                                  propertyName + "' to bean named '" + autowiredBeanName + "'");
41                         }
42                     }
43                     // 清空autowiredBeanNames數組
44                     autowiredBeanNames.clear();
45                 }
46             } catch (BeansException ex) {
47                 throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
48             }
49         }
50     }

分析:

該方法根據屬性類型完成自動注入依賴。

總體流程與根據屬性名稱自動注入差很少:

  • 獲取非簡單屬性名集合,開始遍歷,過濾屬於對象型的屬性。
  • 經過resolveDependency解析屬性,找出正確的匹配(核心函數)。
  • 屬性注入,並進行依賴處理。

DefaultListableBeanFactory#resolveDependency

 1 public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
 2                                     @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
 3 
 4         // 初始化參數名稱發現器,該方法並不會在這個時候嘗試檢索參數名稱
 5         // getParameterNameDiscoverer返回ParameterNameDiscoverer,ParameterNameDiscoverer爲方法參數名稱解析器
 6         descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
 7         // 依賴類型爲Optional類型
 8         if (Optional.class == descriptor.getDependencyType()) {
 9             return createOptionalDependency(descriptor, requestingBeanName);
10             // 依賴類型爲ObjectFactory、ObjectProvider
11         } else if (ObjectFactory.class == descriptor.getDependencyType() ||
12                 ObjectProvider.class == descriptor.getDependencyType()) {
13             return new DependencyObjectProvider(descriptor, requestingBeanName);
14             // javaxInjectProviderClass類注入的特殊處理
15         } else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
16             return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
17         } else {
18             // 爲實際依賴關係目標的延遲解析構建代理
19             // 默認實現返回null
20             Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
21                     descriptor, requestingBeanName);
22             if (result == null) {
23                 // 通用處理邏輯
24                 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
25             }
26             return result;
27         }
28     }

分析:

這裏關注通用處理doResolveDependency:

  1 // DefaultListableBeanFactory
  2 public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
  3                                       @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
  4 
  5         // 注入點
  6         InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
  7         try {
  8             // 針對給定的工廠給定一個快捷的實現方式,例如考慮一些預先解析的信息
  9             // 在進入全部bean常規類型匹配算法以前,解析算法將首次嘗試經過此方法解析快捷方式
 10             // 子類能夠覆蓋此方法
 11             Object shortcut = descriptor.resolveShortcut(this);
 12             if (shortcut != null) {
 13                 // 返回快捷的解析信息
 14                 return shortcut;
 15             }
 16 
 17             // 依賴的類型
 18             Class<?> type = descriptor.getDependencyType();
 19             // 支持Spring的註解@Value
 20             Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
 21             if (value != null) {
 22                 if (value instanceof String) {
 23                     String strVal = resolveEmbeddedValue((String) value);
 24                     BeanDefinition bd = (beanName != null && containsBean(beanName) ?
 25                             getMergedBeanDefinition(beanName) : null);
 26                     value = evaluateBeanDefinitionString(strVal, bd);
 27                 }
 28                 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
 29                 try {
 30                     return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
 31                 } catch (UnsupportedOperationException ex) {
 32                     // A custom TypeConverter which does not support TypeDescriptor resolution...
 33                     return (descriptor.getField() != null ?
 34                             converter.convertIfNecessary(value, type, descriptor.getField()) :
 35                             converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
 36                 }
 37             }
 38 
 39             // 解析複合bean,其實就是對bean的屬性進行解析
 40             // 包括:數組、Collection、Map類型
 41             Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
 42             if (multipleBeans != null) {
 43                 return multipleBeans;
 44             }
 45 
 46             // 查找與類型相匹配的bean
 47             // 返回值構成:key=匹配的beanName,value=beanName對應的實例化bean
 48             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
 49             // 沒有找到,檢驗@autowire的require是否爲true
 50             if (matchingBeans.isEmpty()) {
 51                 // 若是@autowire的require屬性爲true,可是沒有找到相應的匹配項,則拋出異常
 52                 if (isRequired(descriptor)) {
 53                     raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
 54                 }
 55                 return null;
 56             }
 57 
 58             String autowiredBeanName;
 59             Object instanceCandidate;
 60 
 61             if (matchingBeans.size() > 1) {
 62                 // 肯定給定bean autowire的候選者
 63                 // 按照@Primary和@priority的順序
 64                 autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
 65                 if (autowiredBeanName == null) {
 66                     if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
 67                         // 惟一性處理
 68                         return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
 69                     } else {
 70                         // In case of an optional Collection/Map, silently ignore a non-unique case:
 71                         // possibly it was meant to be an empty collection of multiple regular beans
 72                         // (before 4.3 in particular when we didn't even look for collection beans).
 73                         return null;
 74                     }
 75                 }
 76                 instanceCandidate = matchingBeans.get(autowiredBeanName);
 77             } else {
 78                 // We have exactly one match.
 79                 Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
 80                 autowiredBeanName = entry.getKey();
 81                 instanceCandidate = entry.getValue();
 82             }
 83 
 84             if (autowiredBeanNames != null) {
 85                 autowiredBeanNames.add(autowiredBeanName);
 86             }
 87             if (instanceCandidate instanceof Class) {
 88                 instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
 89             }
 90             Object result = instanceCandidate;
 91             if (result instanceof NullBean) {
 92                 if (isRequired(descriptor)) {
 93                     raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
 94                 }
 95                 result = null;
 96             }
 97             if (!ClassUtils.isAssignableValue(type, result)) {
 98                 throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
 99             }
100             return result;
101         } finally {
102             ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
103         }
104     }

分析:

  • 首先嚐試從工廠的快捷實現方式進行解析,若是存在,則直接返回。
  • 支持@Value註解的解析。
  • 解析複合Bean,數組、Map類型的屬性。
  • 而後找出類型相匹配的屬性。

總體邏輯其實不復雜,可debug進行查看。

到此屬性注入已分析得差很少了,接下來是對BeanPostProcessor的處理,後面再分析。這裏先看applyPropertyValues函數,將屬性注入到bean中。

AbstractAutowireCapableBeanFactory#applyPropertyValues

  1 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
  2         if (pvs.isEmpty()) {
  3             return;
  4         }
  5         // 設置BeanWrapperImpl的SecurityContext屬性
  6         if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
  7             ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
  8         }
  9         // MutablePropertyValues類型屬性
 10         MutablePropertyValues mpvs = null;
 11         // 原始類型
 12         List<PropertyValue> original;
 13 
 14         // 得到original
 15         if (pvs instanceof MutablePropertyValues) {
 16             mpvs = (MutablePropertyValues) pvs;
 17             // 屬性已轉換
 18             if (mpvs.isConverted()) {
 19                 // Shortcut: use the pre-converted values as-is.
 20                 try {
 21                     // 爲實例化對象設置屬性值,依賴注入真正的實現,就在這個地方
 22                     bw.setPropertyValues(mpvs);
 23                     return;
 24                 } catch (BeansException ex) {
 25                     throw new BeanCreationException(
 26                             mbd.getResourceDescription(), beanName, "Error setting property values", ex);
 27                 }
 28             }
 29             original = mpvs.getPropertyValueList();
 30         } else {
 31             // 若是pvs不是MutablePropertyValues類型,則直接使用原始類型
 32             original = Arrays.asList(pvs.getPropertyValues());
 33         }
 34 
 35         // 得到TypeConverter=獲取用戶自定義的類型轉換
 36         TypeConverter converter = getCustomTypeConverter();
 37         if (converter == null) {
 38             converter = bw;
 39         }
 40         // 獲取對應的解析器
 41         BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
 42 
 43         // Create a deep copy, resolving any references for values.
 44         List<PropertyValue> deepCopy = new ArrayList<>(original.size());
 45         boolean resolveNecessary = false;
 46         // 遍歷屬性,將屬性轉換爲對應類的對應屬性的類型
 47         for (PropertyValue pv : original) {
 48             // 屬性值不須要轉換
 49             if (pv.isConverted()) {
 50                 deepCopy.add(pv);
 51             // 屬性值須要轉換
 52             } else {
 53                 String propertyName = pv.getName();
 54                 // 原始的屬性值,即轉換以前的屬性值
 55                 Object originalValue = pv.getValue();
 56                 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
 57                 // 轉換屬性值,例如將引用轉換爲IoC容器中實例化對象引用 對屬性值的解析
 58                 Object convertedValue = resolvedValue;  // 轉換以後的屬性值
 59                 boolean convertible = bw.isWritableProperty(propertyName) &&
 60                         !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); // 屬性值是否能夠轉換
 61                 // 使用用戶自定義的類型轉換器轉換屬性值
 62                 if (convertible) {
 63                     convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
 64                 }
 65                 // Possibly store converted value in merged bean definition,
 66                 // in order to avoid re-conversion for every created bean instance.
 67                 // 存儲轉換後的屬性值,避免每次屬性注入時進行轉換
 68                 if (resolvedValue == originalValue) {
 69                     if (convertible) {
 70                         // 設置屬性轉換後的值
 71                         pv.setConvertedValue(convertedValue);
 72                     }
 73                     deepCopy.add(pv);
 74                 // 屬性是可轉換的,且屬性原始值是字符串類型,且屬性的原始類型值不是動態生成的字符串,且屬性的原始值不是集合或者數組類型
 75                 } else if (convertible && originalValue instanceof TypedStringValue &&
 76                         !((TypedStringValue) originalValue).isDynamic() &&
 77                         !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
 78                     pv.setConvertedValue(convertedValue);
 79                     deepCopy.add(pv);
 80                 } else {
 81                     resolveNecessary = true;
 82                     // 從新封裝屬性的值
 83                     deepCopy.add(new PropertyValue(pv, convertedValue));
 84                 }
 85             }
 86         }
 87         // 標記屬性值已經轉換過
 88         if (mpvs != null && !resolveNecessary) {
 89             mpvs.setConverted();
 90         }
 91 
 92         // Set our (possibly massaged) deep copy.
 93         // 進行屬性依賴注入,依賴注入的核心思想在此
 94         try {
 95             bw.setPropertyValues(new MutablePropertyValues(deepCopy));
 96         } catch (BeansException ex) {
 97             throw new BeanCreationException(
 98                     mbd.getResourceDescription(), beanName, "Error setting property values", ex);
 99         }
100     }

分析:

上面的屬性注入只是完成了屬性的獲取,將獲取的屬性封裝在PropertyValues對象中,並無應用到已經實例化的bean上,而applyPropertyValues方法就是完成這一操做的。

該函數主要判斷屬性是否須要進行轉換,若是不須要,則直接進行注入便可,若是須要,則須要進行相應解析,而後進行屬性注入,主要關注setProperty和resolveValueIfNecessary函數(後面再進行分析)。

bean初始化

AbstractAutowireCapableBeanFactory#initializeBean

 1 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
 2         // 安全模式
 3         if (System.getSecurityManager() != null) {
 4             AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
 5                 // 激活Aware方法,對特殊bean處理:Aware、BeanClassLoaderAware、BeanFactoryAware
 6                 invokeAwareMethods(beanName, bean);
 7                 return null;
 8             }, getAccessControlContext());
 9         } else {
10             //  非安全模式下激活Aware方法,對特殊bean處理:Aware、BeanClassLoaderAware、BeanFactoryAware
11             invokeAwareMethods(beanName, bean);
12         }
13 
14         // 後置處理器 before
15         Object wrappedBean = bean;
16         if (mbd == null || !mbd.isSynthetic()) {
17             wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
18         }
19 
20         // 處理初始化方法
21         try {
22             invokeInitMethods(beanName, wrappedBean, mbd);
23         } catch (Throwable ex) {
24             throw new BeanCreationException(
25                     (mbd != null ? mbd.getResourceDescription() : null),
26                     beanName, "Invocation of init method failed", ex);
27         }
28         // 後置處理器 after
29         if (mbd == null || !mbd.isSynthetic()) {
30             wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
31         }
32 
33         return wrappedBean;
34     }

分析:

初始化Bean分爲三大步驟:

  • 激活Aware方法。
  • 後置處理器應用(before/after)。
  • 激活自定義的init方法。

激活Aware方法

 1 // AbstractAutowireCapableBeanFactory
 2 private void invokeAwareMethods(final String beanName, final Object bean) {
 3         if (bean instanceof Aware) {
 4             // BeanNameAware
 5             if (bean instanceof BeanNameAware) {
 6                 ((BeanNameAware) bean).setBeanName(beanName);
 7             }
 8             // BeanClassLoaderAware
 9             if (bean instanceof BeanClassLoaderAware) {
10                 ClassLoader bcl = getBeanClassLoader();
11                 if (bcl != null) {
12                     ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
13                 }
14             }
15             // BeanFactoryAware
16             if (bean instanceof BeanFactoryAware) {
17                 ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
18             }
19         }
20     }

分析: 

這裏主要處理BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,這裏是對Aware接口的處理,後續再進行查漏補缺。

後置處理器應用

BeanPostProcessor 的做用是:若是咱們想要在 Spring 容器完成 Bean 的實例化,配置和其餘的初始化後添加一些本身的邏輯處理,那麼就使用該接口,這個接口給與了用戶充足的權限去更改或者擴展 Spring,是咱們對 Spring 進行擴展和加強處理一個必不可少的接口。

 1 // AbatractAutowireCapableBeanFactory
 2 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
 3             throws BeansException {
 4 
 5         Object result = existingBean;
 6         // 遍歷BeanPostProcessor數組
 7         for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
 8             // 處理
 9             Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
10             if (current == null) {
11                 return result;
12             }
13             // 修改result
14             result = current;
15         }
16         return result;
17     }
18 
19 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
20             throws BeansException {
21 
22         Object result = existingBean;
23         // 遍歷BeanPostProcessor
24         for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
25             // 進行處理
26             // TODO: 2019/4/2 具體處理過程需詳細查看,這裏先走大流程
27             Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
28             // 返回爲空,則返回傳入的Object對象
29             if (current == null) {
30                 return result;
31             }
32             // 修改result
33             result = current;
34         }
35         return result;
36     }

分析:

其實這裏就是獲取自定義的BeanPostProcessor,而後調用其postProcessBeforeInitialization和postProcessAfterInitialization方法進行自定義的業務處理。

激活自定義的init方法

 1 // AbstractAutowireCapableBeanFactory
 2 protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
 3             throws Throwable {
 4 
 5         // 首先先檢查是不是InitializingBean,若是是,則須要調用afterPropertiesSet()
 6         boolean isInitializingBean = (bean instanceof InitializingBean);
 7         if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
 8             if (logger.isDebugEnabled()) {
 9                 logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
10             }
11             // 安全模式
12             if (System.getSecurityManager() != null) {
13                 try {
14                     AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
15                         ((InitializingBean) bean).afterPropertiesSet();
16                         return null;
17                     }, getAccessControlContext());
18                 } catch (PrivilegedActionException pae) {
19                     throw pae.getException();
20                 }
21             } else {
22                 // 屬性初始化處理
23                 ((InitializingBean) bean).afterPropertiesSet();
24             }
25         }
26 
27         if (mbd != null && bean.getClass() != NullBean.class) {
28             String initMethodName = mbd.getInitMethodName();
29             if (StringUtils.hasLength(initMethodName) &&
30                     !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
31                     !mbd.isExternallyManagedInitMethod(initMethodName)) {
32                 // 激活用戶自定義的初始化方法
33                 invokeCustomInitMethod(beanName, bean, mbd);
34             }
35         }
36     }

分析:

在bean標籤中有一個init-method的屬性,該方法的執行就是在這裏。

首先檢查bean是否爲InitializingBean,若是是,則須要執行afterPropertiesSet方法,由於除了可使用init-method來自定義初始化方法外,還能夠實現InitializingBean接口,該接口只有一個afterPropertiesSet方法。

二者執行順序是:先afterPropertiesSet方法,而後是init-method方法。

至此,初始化bean的過程除了循環依賴外,其餘已經大體分析完成。

總結

本篇主要分析了建立bean實例的剩餘流程,主要關注populateBean和initializeBean方法。


by Shawn Chen,2019.04.28,中午。

相關文章
相關標籤/搜索