ホームページ  >  記事  >  Java  >  JavaでのSpringソースコード分析

JavaでのSpringソースコード分析

WBOY
WBOY転載
2023-04-30 23:13:05830ブラウズ

ソースコード解析

1. 事前準備

<code>/**<br> * spring debug<br> * @author huangfu<br> */<br>public class SpringDebug {<br>public static void main(String[] args) {<br>		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(SpringDebugConfig.class);<br>	}<br>}<br></code>

Spring を使ったことがある人なら誰でも、上記の点については特別だと思います。コード行 これには慣れていますが、よく知らない場合は、まずその使い方を学び、それからいくつかのソース コードの基礎となるロジックを詳しく調べることをお勧めします。

Bean を段階的にインスタンス化し、Bean を引き継ぎ、さまざまなライフサイクル クラスを実行する方法を見てみましょう。まず推測してみましょう。Spring がこれらの Bean を読み取るとき、Bean に関する情報は特定のエンティティに保存されているはずです。では、このエンティティは何でしょうか?このクラスは BeanDefinition です。では、このクラスには何が格納されるのでしょうか?これと同様の属性値を定義するサブクラス AbstractBeanDefinition

JavaでのSpringソースコード分析

を見てみましょう。もちろん、作成者はいくつかの属性をインターセプトしています。これよりもはるかに多くのプロパティがあります. その目的は、Bean がインスタンス化されるときに、必要なデータを自分でリフレクションによって取得する必要がないことです. 代わりに、Spring の初期化中にすべて読み込まれます. 必要なときにここから取得することができますbd の概念を理解した後、混乱していませんか?読んだ後はどこに保存されますか?答えは、それを beanFactory に保存することです。そのため、Spring は初期化時に必ず最初に Bean Factory を実装します。 AnnotationConfigApplicationContext と入力すると、初期化されていないことがわかります。どこで初期化されているのでしょうか?ご存知のとおり、クラスが再初期化されると、親クラスのコンストラクターが最初に読み込まれるため、その親クラス GenericApplicationContext:

<code>public GenericApplicationContext() {<br>    //初始化bean的工厂<br>    this.beanFactory = new DefaultListableBeanFactory();<br>}</code>     

を確認する必要があります。予想通り、親クラスに Bean ファクトリが作成されました。ファクトリが利用可能になったので、引き続き AnnotationConfigApplicationContext に戻り、下を見てみます。これが this() を呼び出していることがわかります。独自の空のコンストラクターがあるので、中に入って見てみましょう:

<code>public AnnotationConfigApplicationContext() {<br>    //初始化读取器<br>    this.reader = new AnnotatedBeanDefinitionReader(this);<br>    //初始化扫描器<br>    this.scanner = new ClassPathBeanDefinitionScanner(this);<br>}</code>   

「この時点で、上の図を見ることができます。初期化中に Bean ファクトリがそこにあります。」

JavaでのSpringソースコード分析

「次に、独自の空の構築メソッドでリーダーを初期化します!」

JavaでのSpringソースコード分析

それでは続けましょうAnnotationConfigApplicationContext に戻る 構築メソッド内:

<code>   /**<br>	 * 创建一个新的AnnotationConfigApplicationContext,从给定的带注释的类派生bean定义<br>	 * 并自动刷新上下文。<br>	 * @param annotatedClasses one or more annotated classes,<br>	 * e.g. {@link Configuration @Configuration} classes<br>	 */<br>public AnnotationConfigApplicationContext(Class>... annotatedClasses) {<br>//读取Spring内置的几个的class文件转换为bd  然后初始化bean工厂<br>this();<br>//这一步就是将配置类Config进行了注册并解析bd<br>		register(annotatedClasses);<br>//这一步是核心,Spring的理解全在这一步,这一步理解了也就可以说将Spring理解了70%<br>//内部做一系列的操作如调用bean工厂的后置处理器   实例化类  调用 后置处理器的前置处理   初始化类  调用后置处理器的后置处理 注册事件监听等操作<br>//完成一个类从class文件变为bean的生命周期<br>		refresh();<br>	}</code>     

次のステップは、register メソッドを呼び出すことです。想像してみてください、自動スキャン設定がアノテーション @ComponentScan("com.service") を通じて設定される場合があります。このクラスは通常どこにあるのでしょうか?ちなみに、通常は設定クラスにあります。

<code>@Configuration<br>@ComponentScan("com.service")<br>public class SpringDebugConfig {}</code>     

これらのパッケージの下のクラスをスキャンしたいかどうかを知るには、まず構成クラスの BeanDefinition を解析して、解析したいパッケージを取得できるようにする必要があります。もちろん、この方法ではスキャンされたパケットを解析するだけでなく、他のものも解析しますが、この記事では説明しません。

2. コア関数

わかりました、さらに下に進むと、これらのパッケージの下にあるクラスをスキャンして Bean に変換しようとしていることがわかり、続行しますdown, Go to refresh();このメソッドは素晴らしいです。これは Springbean 初期化全体の中核となるメソッドです。これを理解すれば、Spring のインスタンス化、コールバック、その他の問題を理解できるようになります。

到着後、どのような機能が実行されるかをメソッドごとに分析します。最初は:

1).prepareRefresh();

これがリフレッシュです Bean ファクトリの前の一連の代入操作は、主に、以前に作成された Spring ファクトリのプロパティの多くが空であるためです。このメソッドは、それに一連の初期化値操作を実行することです!

❞ ). getFreshBeanFactory() )
内部 Bean ファクトリをリフレッシュするようにサブクラスに指示します。Bean ファクトリが存在するかどうかを検出します。現在の Bean ファクトリが 1 回だけリフレッシュされているかどうかを判断します。エラーが複数回報告された場合、現在の Bean ファクトリは使用された Bean ファクトリが返されます。このステップが XML の場合、新しいファクトリが作成されて返されます

3). prepareBeanFactory (beanFactory); beanFactory は、独自の組み込みのいくつかを内部的に登録しますBean ポストプロセッサ (通常は BeanPostProcessor と呼ばれます)。このメソッドは実際にはファクトリの再初期化でもあります!
4). postProcessBeanFactory(beanFactory);

コンテキスト サブクラスで Bean ファクトリの後処理を許可します。これは、BeanFactory の準備作業の後にカスタマイズを行うために使用されます。処理が完了しました! ただし、クリックしたメソッドは空のメソッドであることに注意してください。空のメソッドとは何を意味しますか?これは、Spring 開発者が呼び出し元にカスタム拡張機能を使用してもらいたいことを意味します。

❞ BeanFactoryPostProcessors(beanFactory);
❝ BeanFactoryPostProcessors(beanFactory); bd がファクトリーに登録されます。が完了すると、すべての
BeanFactoryPostProcessors
が実行され始めます。

BeanFactoryPostProcessors をカスタマイズするとき、コールバックのタイミングは Spring がすべての BeanDefinition を読んだ後に呼び出します。読者は特定の用途に合わせて Baidu を独自に使用できます。 ❞ BeanPostProcessors(beanFactory);

これは、登録された Bean のポストプロセッサです。つまり、beanPostProcessor とその独自の組み込みプロセッサの実装です。注 プロセッサは呼び出されません。ここでは、Hu プロセッサが Bean ファクトリに登録されています!
beanPostProcessor
インターフェイスの拡張ポイントを使用したことがあるでしょうか?この方法では Spring ファクトリに登録されますが、もちろん登録されるだけで実行されないことに注意してください。覚えていても実行されない!
❞ initMessageSource();

❝彼の目的は、国際的な操作、つまり i18n リソースの初期化を実行することです

8).initApplicationEventMulticaster();
Spring はイベント プログラミングを提供します カプセル化 一般に、イベントは
イベント ブロードキャスター

(イベントの発行)、

イベント リスナー
(イベントのリッスン) の 3 つの役割に分けられます。 )、
イベント ソース
(特定のイベント情報) の 3 つの役割。このメソッドの目的は、イベント ブロードキャスターを初期化することです。
❞ onRefresh(); !

10). registerListeners();Spring イベント リスナーを登録します。前述したように、イベント リスナーの初期化と登録は次のとおりです

##11).finishBeanFactoryInitialization(beanFactory);
#❝
このメソッドは重要なポイントで、残りのすべての (遅延初期化ではない) シングルトンをインスタンス化することです。いわゆる Bean のインスタンス化、インジェクション、循環依存関係の解決、コールバック
beanPostProcessor
およびその他の操作はすべてここで実装されています。

12).finishRefresh();
最後のステップ: 対応するイベントを公開します。 Spring の組み込みイベント

以上がJavaでのSpringソースコード分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。