Spring @Autowireアノテーションソースコードの詳細説明

目次

1: トリガー方法:

2: ソースコード分析

2.1 スキャン注入ポイント

2.2 属性の割り当て


1: トリガー方法:

1. 各 Bean がインスタンス化された後、Spring コンテナは AutowireAnnotationBeanPostProcessor の postProcessMergedBeanDefinition メソッドを呼び出して、注入ポイントをスキャンします。

2. Spring が各 Bean をインスタンス化し、注入ポイントをスキャンした後、Bean インジェクションのために PopulateBean を呼び出し、postProcessPropertyValues メソッドを呼び出します。

2: ソースコード分析

2.1 スキャン注入ポイント

@Autowire アノテーションをプロパティ、コンストラクター、および set メソッドに追加することで、Bean に依存関係を注入できます。

package service;

import org.springframework.beans.factory.annotation.Autowired;

public class UserService1 {

    @Autowired
    private  OrderService orderService;

    public void test(){
        System.out.println(orderService);
    }

}

まず、注入ポイントを見つけます。Bean を作成するとき、インスタンス化した後、

AbstractAutowireCapableBeanFactory.java

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

....

  if (!mbd.postProcessed) {
				try {
					//todo 在实例化后,对MergeBeanDefinition进行属性修改
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}

..

}

applyMergedBeanDefinitionPostProcessors メソッドを入力し、processor.postProcessMergedBeanDefinition(mbd,beanType,beanName); を呼び出します。

	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
			processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
		}
	}

@Autowire アノテーション付きクラスを処理する場合の AutowiredAnnotationBeanPostProcessor

 「findAutowiringMetadata(beanName,beanType,null)」と入力します。

 

buildAutowiringMetadata(final Class<?> clazz) メソッドで、プロパティをループし、メソッドをループします。

、プロパティとメソッドは静的であってはならず、フィールドと必須を AutowireFieldElement 項目にカプセル化し、それをcurrElements に追加し、最後に要素にマージします。 

 

上記は依存性注入による注入ポイントの発見の処理であり、プロパティの割り当てはまだ行われていません。

2.2 属性の割り当て

Bean がインスタンス化された後、循環依存関係、属性の入力、初期化、および Bean の破棄が実行されます。

「populateBean(beanName, mbd,instanceWrapper)」と入力します。

主にpostProcessPropertiesに基づいて属性注入を実行します

ここで注入ポイントと属性の割り当てを見つけてください。注入ポイントの検索は上で分析され、属性の割り当ては以下で分析されます。

 @Autowire アノテーションによってフィールドに追加された inject() メソッドは、AutowiredFieldElement 内部クラスにあります。

 初めてsolveFieldValue(field,bean,beanName) にキャッシュがない場合、シングルトン Bean は 1 回だけ作成され、プロパティは 1 回注入されるため、キャッシュはプロトタイプ Bean 用になります。

最後に、Bean が検出され、DefaultListableBeanFactory.java に返されます。

1. 最初に @Value アノテーションを処理します

2. Map Bean か List 複合 Bean かを判断し、その中で findAutowireCandidates メソッドを呼び出し、Spring コンテナに移動してタイプに従って検索します。

Map<String, Object>matchingBeans = findAutowireCandidates(beanName, valueType, 
      new MultiElementDescriptor(descriptor));

3. タイプに従って Spring コンテナ内の Bean を検索します。返されるキーは beanName です。値は Bean オブジェクトまたは Bean クラスです。

Map<String, Object>matchingBeans = findAutowireCandidates(beanName, type, descriptor);

4. matcingbeans.size >1 で、タイプに基づいて複数の Bean が見つかった場合は、名前に基づいてそれらを見つけて呼び出します。

destroyAutowireCandidate メソッドは、最初に @primary アノテーションが追加されているかどうかを判断し、追加されている場合は Bean を返し、次に Bean の優先順位を決定して、記述子の名前 (フィールドの名前またはフィールドの名前) と照合します。設定されたメソッドのパラメータ。最後に beanName が返されますが、これらのアノテーションが追加されていない場合は null が返されます。

5. ステップ 4 で返されたブルが @Autowire で構成されておらず (required=false)、Bean が複合タイプではない場合、単一の一致する Bean が予期されたが beanName が見つかったという例外がスローされます。

6.beanNameに従って、bean/beanクラスを取得して返します。

 

おすすめ

転載: blog.csdn.net/qq_24186017/article/details/128159912