前言:前面分析了doCreateBean中的createBeanInstance函數,接下來分析其剩餘流程。
首先貼上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)的不同,調用不同的方法來注入屬性值。
AbstractAutowireCapableBeanFactory#autowireByName
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 }
該函數為根據屬性名稱完成自動依賴注入。
- 首先擷取bean對象的非簡單屬性。非簡單屬性:類型為對象類型的屬性,但并不是将所有的對象類型都會找到,比如8個原始類型:String、Number等類型都會被忽略。
- 循環周遊屬性名,然後為指定名稱的屬性指派。
- 然後進行屬性依賴注入。
AbstractAutowireCapableBeanFactory#unsatisfiedNonSimpleProperties
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,中午。