目次
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クラスを取得して返します。