インタビューメモ: Spring フレームワークとそのソース コード実装の使用に関する知識ポイント

ヒント:記事作成後に目次を自動生成することもできますが、生成方法については右のヘルプを参照してください。


1. Spring Framework の概要とその利点

Spring は、軽量の IoC および AOP コンテナー フレームワークです。これは、Java アプリケーションの基本サービスを提供するフレームワークのセットで、エンタープライズ アプリケーションの開発を簡素化し、開発者がビジネス ニーズのみに気を配れば済むように設計されています。主に次の 7 つのモジュールが含まれています。

  • Spring Context: フレームワークベースの Bean アクセスメソッドとエンタープライズレベルの機能 (JNDI、スケジュールされたタスクなど) を提供します。
  • Spring Core: コア クラス ライブラリ。すべての関数はこのクラス ライブラリに依存し、IOC および DI サービスを提供します。
  • Spring AOP: AOP サービス。
  • Spring Web: 基本的な包括的な Web 指向の機能と、Struts2 などの一般的なフレームワークのサポートを提供します。Spring は、これらのフレームワークを管理し、Spring リソースをフレームワークに挿入し、これらのフレームワークの前後にインターセプターを挿入できます。
  • Spring MVC: Web アプリケーション用の Model-View-Controller、つまり MVC 実装を提供します。
  • Spring DAO: JDBC の抽象カプセル化。データ アクセス例外の処理を簡素化し、JDBC トランザクションを均一に管理できます。
  • Spring ORM: 既存の ORM フレームワークのサポート。

以下の図は Spring 4.x バージョンに対応しています。5.x バージョンの Web モジュールのポートレット コンポーネントは廃止されました。

ここに画像の説明を挿入します

春の利点:

  1. Spring は低侵入設計を採用しており、コード汚染は非常に低いです。
  2. Spring の DI メカニズムは、オブジェクト間の依存関係をフレームワークで処理できるようにし、コンポーネントの結合を減らします。
  3. Spring は、セキュリティ、トランザクション、ログ、アクセス許可などのいくつかの一般的なタスクの一元管理をサポートする AOP テクノロジを提供し、それによって再利用性が向上します。
  4. Spring は、主流のアプリケーション フレームワークの統合サポートを提供します。

2. Spring IOC と AOP の理解

1、春のIOC

1.IOCとは何ですか?

IOC、Inversion of Control、制御の反転とは、オブジェクトの制御を Spring フレームワークに移すことを指し、Spring はオブジェクトのライフサイクル (作成、破棄など) とオブジェクト間の依存関係を制御します。

最も直観的な表現は、以前はオブジェクトを作成するタイミングと主導権は自分で制御されていたため、オブジェクト内で別のオブジェクトを使用する場合は、新しい命令を通じて依存オブジェクトを積極的に作成し、そのオブジェクトを破棄する必要があるということです。使用後 (接続など)、オブジェクトは常に他のインターフェイスまたはクラスと結合されます。IOC は特別なコンテナを使用してオブジェクトの作成を支援し、すべてのクラスは Spring コンテナに登録されます。オブジェクトが必要なときに、率先して new を使用する必要はなくなりました。Spring コンテナに指示し、次に Spring に指示するだけで済みます。システムが適切なタイミングで実行されると、必要なオブジェクトが与えられます。つまり、特定のオブジェクトに対して、それが参照するオブジェクトのライフサイクルを制御していましたが、IOC ではすべてのオブジェクトが Spring によって制御され、オブジェクトのライフサイクルは Spring によって制御されなくなりました。オブジェクトですが Spring コンテナー Spring コンテナーは依存オブジェクトの作成、検索、挿入に役立ちますが、参照オブジェクトは依存オブジェクトを受動的に受け入れるだけなので、これは制御の反転と呼ばれます。

2.DIとは何ですか?

IOC の重要なポイントの 1 つは、プログラムの実行中に、オブジェクトに必要な他のオブジェクトを動的に提供することです。これは、DI (Dependency Injection、依存性注入) を通じて実現されます。つまり、アプリケーションは、IoC コンテナーに依存して動的に注入します。オブジェクトに必要な外部依存関係。Spring の DI は特にリフレクションを通じて挿入され、プログラムは実行中にオブジェクトを動的に生成し、オブジェクト メソッドを実行し、オブジェクトのプロパティを変更できます。

3. IOC の原則:

SpringのIoCの実装原理はファクトリモード+リフレクション機構であり、SpringコンテナではBeanオブジェクトがどのようにIoCコンテナに登録されるのか、Beanオブジェクトのロード、インスタンス化、初期化の詳細な処理はこちらで読むことができます。記事: Spring の Bean ロードプロセス


2. Spring AOP の理解

OOP はオブジェクト指向であるため、開発者は垂直方向の関係を定義できますが、水平方向の関係を定義するのには適していないため、大量のコードの重複が発生し、各モジュールの再利用に役立ちません。

AOP は一般にアスペクト指向と呼ばれます。オブジェクト指向の補足として、ビジネスとは関係がないが、複数のオブジェクトに影響を与えるパブリックな動作やロジックを再利用可能なモジュールに抽出してカプセル化するために使用されます。このモジュールは「アスペクト」と呼ばれます。 、システム内の重複コードが減り、モジュール間の結合が減り、システムの保守性が向上します。権限認証、ロギング、トランザクション処理に使用できます。

AOP 実装の鍵はプロキシ モードにあり、AOP プロキシは主に静的プロキシと動的プロキシに分けられます。静的プロキシは AspectJ によって表され、動的プロキシは Spring AOP によって表されます。

  • AspectJ は静的プロキシであり、コンパイル時拡張とも呼ばれます。AOP フレームワークは、コンパイル フェーズ中に AOP プロキシ クラスを生成し、AspectJ (アスペクト) を Java バイトコードに織り込みます。実行時、それは拡張 AOP オブジェクトになります。

  • Spring AOP によって使用される動的プロキシ。いわゆる動的プロキシとは、AOP フレームワークがバイトコードを変更せず、実行するたびにメソッドの AOP オブジェクトをメモリ内に一時的に生成することを意味します。この AOP オブジェクトには、次のすべてのメソッドが含まれています。ターゲット オブジェクトが指定され、特定のカット ポイントで拡張処理が実行され、元のオブジェクトのメソッドがコールバックされます。

    Spring AOP の動的プロキシには、JDK 動的プロキシと CGLIB 動的プロキシという 2 つの主な方法があります。

    ① JDK 動的プロキシはインターフェイス プロキシのみを提供し、クラス プロキシをサポートせず、インターフェイスを実装するためにプロキシ クラスを必要とします。JDK 動的プロキシのコアは、InvocationHandler インターフェイスと Proxy クラスです。プロキシ オブジェクトを取得するときに、Proxy クラスを使用して、ターゲット クラスのプロキシ クラス (つまり、最終的な実際のプロキシ クラス、このクラスは継承元のプロキシ クラス) を動的に作成します。プロキシと定義したインターフェイスを実装します)。プロキシ オブジェクトが実際のオブジェクトのメソッドを呼び出すと、InvocationHandler は invoke() メソッドのリフレクションを通じてターゲット クラスのコードを呼び出し、横断的なロジックとビジネスを動的に織り交ぜます。

    InvocationHandler の invoke(Object proxy,Method method,Object[] args): proxy は、最終的に生成されたプロキシ オブジェクトです。method は、プロキシ ターゲット インスタンスの特定のメソッドです。args は、プロキシ ターゲット インスタンスのメソッドの特定の入力パラメータです。使用されます。メソッドのリフレクションが呼び出されたとき。

    ② プロキシクラスがインターフェースを実装していない場合、Spring AOP は CGLIB を使用してターゲットクラスを動的にプロキシすることを選択します。CGLIB (コード生成ライブラリ) は、実行時に指定されたクラスのサブクラス オブジェクトを動的に生成し、特定のメソッドをオーバーライドし、AOP を実装するための拡張コードを追加できるコード生成クラス ライブラリです。CGLIB は継承による動的プロキシであるため、クラスが Final としてマークされている場合、CGLIB を動的プロキシとして使用することはできません。

  • 静的プロキシと動的プロキシの違いは、AOP プロキシ オブジェクトを生成するタイミングにあり、相対的に言えば、AspectJ の静的プロキシ方式の方がパフォーマンスは優れていますが、AspectJ は処理に特定のコンパイラを必要としますが、Spring AOP は処理に特定のコンパイラを必要としません。

IOC を使用すると、連携するコンポーネントを疎結合のままにすることができます。一方、AOP プログラミングを使用すると、アプリケーションのすべての層にまたがる機能を再利用可能な機能コンポーネントに分離できます。


3. AOP関連の名詞概念

(1) ジョインポイント: プログラムの実行中に実行されるメソッドを指します。Spring AOP では、接続ポイントは常にメソッドの実行を表します。

(2) 側面: 抽出された共通モジュールを使用して、複数のオブジェクトを横断的に使用できます。アスペクト アスペクトは、ポイントカット ポイントカットとアドバイス通知の組み合わせとして見ることができ、アスペクトは複数のポイントカットとアドバイスで構成できます。

Spring AOP では、@AspectJ アノテーションを使用してアスペクトをクラスに実装できます。

(3) ポイントカット: ポイントカットは、どの結合ポイントをインターセプトするかを定義するために使用されます。

ポイントカットは、実行モードと注釈モードに分かれています。実行メソッドはパス式を使用して、add* や search* をインターセプトするように指定するなど、インターセプトするメソッドを指定できます。アノテーション メソッドは、どのアノテーション変更コードをインターセプトするかを指定できます。

(4) アドバイス: 参加ポイントで実行されるアクション、つまり、権限チェックサム、ロギングなどの拡張ロジックを指します。通知には「周囲」「前」「後」「返し後」「投げた後」などさまざまな種類があります。

(5) ターゲット オブジェクト (Target): 接続ポイントを含むオブジェクト。アドバイスされるオブジェクト (Advice) とも呼ばれます。Spring AOP は動的プロキシを通じて実装されるため、このオブジェクトは常にプロキシ オブジェクトです。

(6)ウィービング:動的プロキシを介してターゲットオブジェクト(Target)(すなわち、Joinポイント)のメソッド内の拡張ロジック(Advice)を実行するプロセス。

(7) 導入: 通知されたクラスにメソッドまたはフィールドを追加します。Spring では、プロキシされたオブジェクトに新しいインターフェイス (および対応する実装) を導入できます。たとえば、インポートを使用して Bean に IsModified インターフェイスを実装させ、キャッシュ メカニズムを簡素化できます。


4. AOP 通知 (アドバイス) にはどのような種類がありますか?

(1) Before Advice: 結合点の前に実行されるアドバイス。

(2) After Advice: 接続ポイントが終了したときに実行される通知 (正常に終了したか、異常終了したかに関係なく)。

(3) アラウンドアドバイス: 接続ポイントを囲むアドバイスで、最も強力なタイプの通知です。サラウンド通知により、メソッド呼び出しの前後にカスタマイズされた動作を完了できます。また、ジョインポイントの実行を継続するか、独自の戻り値を直接返すか、例外をスローして実行を終了するかを選択することもできます。

(4) AfterReturning Advice: 接続ポイントが正常に完了した後に実行されるアドバイス (接続ポイントが例外をスローした場合は実行されません)

(5) AfterThrowing アドバイス: メソッドが例外をスローして終了するときに実行されるアドバイス


3. 春にはどのようなデザインパターンが使用されますか?

Spring で使用されるデザイン パターンとその実施形態:

シングルトン モード: Spring の Bean はデフォルトでシングルトンです

ファクトリ モード: Spring はファクトリ モードを使用して、BeanFactory および ApplicationContext を通じて Bean オブジェクトを作成します。

プロキシ モード: Spring の AOP 関数は、JDK の動的プロキシと CGLIB バイトコード生成テクノロジを使用します。

テンプレート メソッド パターン: jdbcTemplate、hibernateTemplate、およびデータベース上で動作する Spring の Template で終わるその他のクラスは、テンプレート パターンを使用します。

ラッパー パターン: 私たちのプロジェクトは複数のデータベースに接続する必要があり、さまざまな顧客が訪問するたびにニーズに応じてさまざまなデータベースにアクセスします。このモデルにより、顧客のニーズに応じて異なるデータ ソースを動的に切り替えることができます。

オブザーバー パターン: Spring のイベント駆動モデルは、オブザーバー パターンの古典的なアプリケーションです。

戦略モード: たとえば、リソース実装クラスは、さまざまなリソース ファイルに対してさまざまなリソース取得戦略を実装します。

アダプター モード: Spring AOP の拡張または通知 (アドバイス) はアダプター モードを使用し、Spring MVC もコントローラーを適応させるためにアダプター モードを使用します。


4. Springコンテナの起動処理

1.初始化Spring容器組み込み BeanPostProcessor の BeanDefinition をコンテナに登録します。

  1. Bean オブジェクトの生成に使用される BeanFactory [DefaultListableBeanFactory] ​​ファクトリをインスタンス化します。
  2. BeanDefinitionReader アノテーション構成リーダーをインスタンス化します。これは、特定のアノテーション (@Service、@Repository など) を持つクラスを読み取り、BeanDefinition オブジェクトに変換するために使用されます (BeanDefinition は、Spring における非常に重要な概念です。Bean に関するすべての情報が保管されます)。オブジェクト。シングルトンであるかどうか、遅延読み込みであるかどうか、factoryBeanName などの機能情報)
  3. ClassPathBeanDefinitionScanner パス スキャナーをインスタンス化します。これは、指定されたパッケージ ディレクトリをスキャンして Bean オブジェクトを見つけるために使用されます。

2. 構成クラスを解析し、BeanDefinition注册コンテナに転送します。

3.调用refresh()方法コンテナを更新します。

  1. prepareRefresh() が更新する前の前処理:
  2. getFreshBeanFactory(): コンテナの初期化時に作成された BeanFactory を取得します。
  3. prepareBeanFactory(beanFactory): BeanFactory の前処理作業で、いくつかのコンポーネントをコンテナーに追加します。
  4. postProcessBeanFactory(beanFactory): サブクラスはこのメソッドをオーバーライドして、BeanFactory が作成され前処理された後にさらに設定を行います。
  5. invokeBeanFactoryPostProcessors(beanFactory): BeanFactory の標準初期化後に BeanFactoryPostProcessor を実行するメソッド、つまり BeanFactory のポストプロセッサー:
  6. registerBeanPostProcessors(beanFactory): Bean ポストプロセッサ BeanPostProcessor をコンテナに登録します。その主な機能は、Spring が Bean を初期化するプロセスに介入し、それによってプロキシ、自動インジェクション、循環依存関係などの機能を完了することです。
  7. initMessageSource(): MessageSource コンポーネントを初期化します。主に国際化機能、メッセージ バインディング、およびメッセージ解析に使用されます。
  8. initApplicationEventMulticaster(): リスナーの登録時に使用されるイベント ディスパッチャーを初期化します。
  9. onRefresh(): このメソッドをオーバーライドするのはサブコンテナとサブクラスに任せます。コンテナが更新されるときのロジックをカスタマイズできます。
  10. registerListeners(): リスナーの登録: コンテナー内のすべての ApplicationListeners をイベント ディスパッチャーに登録し、前の手順で生成されたイベントをディスパッチします。
  11. finishBeanFactoryInitialization(beanFactory): 残りのすべての単一インスタンス Bean を初期化します。コア メソッドは preInstantiateSingletons() で、getBean() メソッドを呼び出してオブジェクトを作成します。
  12. finishRefresh(): BeanFactory コンテナのリフレッシュ完了イベントを発行します。

詳細については、次の記事を参照してください: Spring コンテナーの起動プロセス_Zhang Weipeng のブログ


5. BeanFactory と ApplicationContext の違いは何ですか?

BeanFactory と ApplicationContext は Spring の 2 つのコア インターフェイスであり、どちらも Spring コンテナとして使用できます。ApplicationContext インターフェースは、BeanFactory のサブクラスとして、BeanFactory の機能を提供するだけでなく、より完全なフレームワーク機能も提供します。

ビーンファクトリー アプリケーションコンテキスト
遅延読み込みを使用します インスタントロードを使用します
次の構文を使用してリソース オブジェクトを明示的に提供します。 リソースオブジェクト自体を作成および管理します
国際化とリソース ファイル アクセスはサポートされていません 国際化とリソース ファイル アクセス (URL とファイル (ResourceLoader)) をサポートします。
依存関係ベースのアノテーションはサポートされていません 依存関係ベースのアノテーションをサポート

BeanFactory と ApplicationContext の長所と短所の分析:

BeanFactory の長所と短所:

  • 利点: アプリケーションは起動時にほとんどリソースを消費しません。リソース要件が高いアプリケーションほど利点が大きくなります。
  • デメリット:走行速度が比較的遅くなります。さらに、null ポインタ例外エラーが発生する可能性があり、Bean ファクトリを通じて作成された Bean のライフ サイクルが簡素化されます。

ApplicationContext の長所と短所:

  • 利点: すべての Bean は起動時にロードされ、システムは迅速に実行されます。システムの起動時に、システム内の構成の問題を発見できます。
  • 短所: 時間のかかる操作をシステムの起動時に実行すると、すべてのオブジェクトを事前にロードできますが、大量のメモリを消費することが欠点です。

6. Spring が循環依存関係を解決する方法

Spring が循環依存関係を処理する状況は 3 つあります。

  1. コンストラクターの循環依存関係: 処理できず、BeanCurrentlylnCreationException がスローされます。
  2. シングルトン モードで循環依存関係をセッター: 「3 レベル キャッシュ」を通じて循環依存関係を処理します。
  3. 非シングルトン モードでのセッターの循環依存関係: 処理できません

Spring でのシングルトン オブジェクトの初期化は、主に 3 つのステップに分かれています。

  1. createBeanInstance: インスタンス化。実際にオブジェクトのコンストラクター メソッドを呼び出してオブジェクトをインスタンス化します。
  2. PopulateBean: 属性の入力: このステップは主に、複数の Bean の依存属性を入力することです。
  3. InitializeBean: Spring XML で init メソッドを呼び出します。

上で説明したシングルトン Bean の初期化手順から、循環依存関係は主に最初の部分と 2 番目の部分で発生することがわかります。つまり、コンストラクターの循環依存性とフィールドの循環依存性です。

キャッシュ 使用
Map<String, Object> シングルトンモードで作成されたBeanインスタンスを格納します
Map<String, Object> EarlySingletonObjects シングルトン モードで作成中の Bean インスタンスを格納します (プロパティはまだ設定されていません)。
Map<String, ObjectFactory<?>> singletonFactories Bean ファクトリ オブジェクトを格納します。ObjectFactory オブジェクトは、シングルトン モードで事前に公開された Bean インスタンスへの参照を格納するために使用されます。

例: A のフィールドまたはセッターは B のインスタンス オブジェクトに依存し、B のフィールドまたはセッターは A のインスタンス オブジェクトに依存します。

これは循環依存関係の状況です。1 つ目は、初期化の最初のステップ (createBeanINstance インスタンス化) を完了し、事前にそれ自体を singletonFactories に公開します。

この時点で、初期化の 2 番目のステップを実行し、オブジェクト B に依存していることがわかります。この時点で get(B) を試みると、B がまだ作成されていないことが判明したため、作成プロセスを実行します。初期化の最初のステップで、B はオブジェクト B に依存していることがわかりました。A なので、get(A) を試し、第 1 レベルのキャッシュ singletonObjects を試し (A は完全に初期化されていないため、絶対にそうではありません)、2 番目のキャッシュを試しました。 -レベルのキャッシュearlySingletonObjects(これもそうではありません)、第3レベルのキャッシュsingletonFactoriesを試しました。これは、Aが事前に ObjectFactory を通じて自分自身を公開しているため、Bは ObjectFactory.getObject を通じてAオブジェクトを取得できるためです(Aは完全に初期化されていませんが、それよりも優れています) B は A オブジェクトを取得した後、初期化ステージ 1、2、および 3 を正常に完了します。完全な初期化後、それを自分で 1 次キャッシュの singletonObjects に置きます。

このとき、A に戻ります。この時点で、A は B のオブジェクトを取得し、自身の初期化フェーズ 2 と 3 を正常に完了できます。最後に、A も初期化を完了し、1 次キャッシュの singletonObject に入りました。そしてさらに幸運なことに、 B は A のオブジェクト参照を取得したため、B が現在保持している A オブジェクトは初期化されています。

コンストラクターの相互注入によって引き起こされる循環依存関係を解決する:
前述したように、Spring はシングルトン モードの setter() メソッドによる依存関係注入によって引き起こされる循環依存関係の問題を自動的に解決できます。コンストラクターを介した依存関係注入によって引き起こされる循環依存関係の問題を自動的に解決する方法はありませんが、この場合は @Lazy アノテーションを使用して解決できます。

つまり、クラス A とクラス B の両方がコンストラクターを通じて注入される場合、A または B のコンストラクターの仮パラメーターに @Lazy アノテーションを追加して、遅延読み込みを実装できます。@Lazy の実装原則は、オブジェクトをインスタンス化するときに、パラメーターまたは属性が @Lazy アノテーションで変更されていることが判明した場合、依存オブジェクトは直接作成されず、動的プロキシを使用してプロキシが作成されることです。クラス。


7. Spring Bean のライフサイクル

簡単に言えば、Spring Bean のライフサイクルには次の 4 つの段階しかありません: インスタンス化 --> プロパティの割り当て Populate --> 初期化 --> 破棄

具体的には、Spring Bean のライフサイクルには、次の図のプロセスが含まれます。
ここに画像の説明を挿入します
作成プロセス:

  1. 实例化bean:
    BeanFactory コンテナの場合、顧客がコンテナから初期化されていない Bean を要求した場合、または Bean を初期化するときに、別の初期化されていない依存関係を注入する必要がある場合、コンテナはインスタンス化のために createBean を呼び出します。

    ApplicationContext コンテナの場合、コンテナが開始されると、BeanDefinition オブジェクト内の情報を取得してすべての Bean がインスタンス化されます。

  2. 设置对象属性(依赖注入):
    インスタンス化されたオブジェクトは BeanWrapper オブジェクトにカプセル化され、BeanDefinition と BeanWrapper が提供するプロパティ設定インターフェースの情報をもとに Spring がプロパティ設定と依存性注入を完了します。

  3. 处理Aware接口:
    依存関係が Aware インターフェースを通じて宣言されている場合、コンテナ インフラストラクチャ レベルでの Bean の依存関係が注入されます。Aware インターフェースは、独自の属性の一部を認識します。コンテナ管理 Bean は通常、コンテナのステータスを認識したり、コンテナを直接使用したりする必要はありません。ただし、場合によっては、Bean 内で IOC コンテナを操作する必要があります。このとき、Beanにコンテナの認識を設定する必要があります。SpringIOC コンテナもこの機能を提供しており、この機能は特定の Aware インターフェイスを通じて実現されます。例えば:

    • Bean が BeanNameAware インターフェースを実装している場合、Bean はコンテナー内でその名前を知ることができます。
    • Bean が BeanFactoryAware インターフェースを実装している場合、このメソッドを使用して他の Bean を取得できます。
    • Bean が BeanNameAware インターフェースを実装している場合は、setBeanName() メソッドを呼び出して Bean の名前を渡します。
    • Bean が BeanClassLoaderAware インターフェースを実装している場合は、setBeanClassLoader() メソッドを呼び出して、ClassLoader オブジェクトのインスタンスを渡します。
    • Bean が BeanFactoryAware インターフェースを実装している場合は、setBeanFactory() メソッドを呼び出して、BeanFactory オブジェクトのインスタンスを渡します。
  4. BeanPostProcessor前置处理:
    BeanPostProcess の初期化前メソッド postProcessBeforeInitialization がすぐに呼び出されます。その主な機能は、Spring がインスタンス化を完了した後、初期化前に、Spring コンテナによってインスタンス化された Bean にカスタム処理ロジックを追加することです。AOPに少し似ています

  5. InitializingBean注:
    BeanFactoryPostProcessor インターフェースの afterPropertiesSet メソッドを実装する場合は、プロパティが設定された後にいくつかのカスタム処理を実行します。

  6. init-method:
    Bean 自体によって定義された init メソッドを呼び出して、初期化関連の作業を実行します (たとえば、Bean が Spring 構成ファイルで init-method 属性を構成する場合、その構成された初期化メソッドが自動的に呼び出されます)。

  7. BeanPostProcessor后置处理:
    BeanPostProcess の初期化後メソッド postProcessAfterInitialization を呼び出して、Bean の初期化後にカスタム作業を実行します。

上記の作成が完了すると、このBeanをアプリケーションで使用できるようになります。

破棄プロセス:
Bean が使用されなくなったら、ビーンを破棄する必要があります。

  1. DisposableBean インターフェースが実装されている場合は、destroy メソッドが呼び出されます。
  2. destroy-method 属性が設定されている場合は、設定されている破棄メソッドが呼び出されます。

概要: 生成過程と破壊過程の 2 つの主要な側面を主に理解します。

  • 作成プロセス: まず Bean をインスタンス化し、Bean のプロパティを設定し、実装する Aware インターフェース (主に BeanFactoryAware インターフェース、BeanFactoryAware、ApplicationContextAware) に従って依存関係情報を設定し、次に BeanPostProcess の postProcessBeforeInitialization メソッドを呼び出してカスタム ロジックを完成します。 afterPropertiesSet メソッドは、プロパティが設定された後にいくつかのカスタム作業を実行し、Bean 自体によって定義された init メソッドを呼び出して初期化関連の作業を行い、その後、postProcessAfterInitialization を呼び出して Bean の初期化後にカスタム作業を行います。これら 4 つのメソッドの呼び出しは、AOP に似ています。この時点でBeanの初期化が完了し、Beanを使用できるようになります。
  • 破棄処理:DisposableBeanのdestroyメソッドが実装されている場合はそれを呼び出し、カスタムのdestroyメソッドが実装されている場合はそれを呼び出します。

8. AOPの実装方法は何ですか?

AOP を実装するためのテクノロジーは、主に次の 2 つのカテゴリに分類されます。

  • 静的プロキシ - AOP フレームワークによって提供されるコマンドを使用してコンパイルすることを指し、コンパイル フェーズ中に AOP プロキシ クラスを生成できるため、コンパイル時拡張とも呼ばれます。
    • コンパイル時ウィービング (特別なコンパイラー実装)
    • クラスロード時のウィービング (特別なクラスローダー実装)。
  • 動的プロキシ - AOP 動的プロキシ クラスは、実行時にメモリ内に「一時的に」生成されるため、ランタイム拡張機能とも呼ばれます。
    • JDK 動的プロキシ: リフレクションを通じてプロキシされたクラスを受け取り、プロキシされたクラスがインターフェイスを実装する必要があります。JDK 動的プロキシの中心となるのは、InvocationHandler インターフェイスと Proxy クラスです。
    • CGLIB 動的プロキシ: ターゲット クラスがインターフェイスを実装していない場合、Spring AOP は CGLIB を使用してターゲット クラスを動的にプロキシすることを選択します。CGLIB (コード生成ライブラリ) は、実行時に特定のクラスのサブクラスを動的に生成できるコード生成クラス ライブラリです。CGLIB は継承による動的プロキシであるため、クラスが としてマークされている場合、CGLIB を動的プロキシとして使用できないことに注意してくださいfinal。プロキシ。

9. Spring トランザクションの使用方法と実装方法

Spring トランザクションの本質は、実際にはデータベースによるトランザクションのサポートであり、データベース トランザクションのサポートがなければ、Spring はトランザクション機能を提供できません。Spring は統一されたトランザクション管理インターフェイスのみを提供しており、具体的な実装は各データベース自体によって実装され、データベース トランザクションの送信とロールバックは、REDO ログと UNDO ログを通じて実装されます。Spring は、一貫性を維持するために、トランザクションの開始時に現在の環境で設定されている分離レベルに従ってデータベースの分離レベルを調整します。

1. Spring トランザクションの種類:

Spring は、プログラムによるトランザクション管理と宣言的なトランザクション管理という 2 つの方法をサポートしています。

  1. プログラムによるトランザクション管理は、TransactionTemplate を使用します。
  2. 宣言型トランザクション管理は AOP に基づいて構築されています。その本質は、AOP 関数を使用して前後のメソッドをインターセプトし、トランザクション処理関数をインターセプト メソッドに織り込むことです。つまり、ターゲット メソッドが開始される前にトランザクションを開始し、ターゲット メソッドの実行後にトランザクションが実行されます。実行状況に応じてコミットまたはロールバックされます。

宣言型トランザクションの最大の利点は、ビジネス ロジック コードにトランザクション管理コードを混在させる必要がないことです。構成ファイルで関連するトランザクション ルール宣言を行うか、@Transactional アノテーションを使用してトランザクション ルールをビジネス ロジックに適用するだけで済みます。 、ビジネスコードの汚染を軽減します。唯一の欠点は、最も細かい粒度はメソッド レベルにのみ適用でき、プログラム トランザクションのようなコード ブロック レベルには適用できないことです。

2. Spring のトランザクション伝播メカニズム:

Spring トランザクション伝播メカニズムでは、複数のトランザクションが同時に存在する場合に Spring がこれらのトランザクションの動作をどのように処理するかについて説明します。トランザクション伝播メカニズムは実際には単純な ThreadLocal を使用して実装されているため、呼び出されたメソッドが新しいスレッドで呼び出される場合、トランザクション伝播は実際には失敗します。

  1. PROPAGATION_REQUIRED: (デフォルトの伝播動作) 現在トランザクションがない場合は新しいトランザクションを作成し、現在トランザクションがある場合はトランザクションに参加します。
  2. PROPAGATION_REQUIRES_NEW: トランザクションが現在存在するかどうかに関係なく、実行する新しいトランザクションを作成します。
  3. PROPAGATION_SUPPORTS: 現在トランザクションが存在する場合はトランザクションに参加し、現在トランザクションが存在しない場合は非トランザクションとして実行します。
  4. PROPAGATION_NOT_SUPPORTED: 非トランザクション方式で操作を実行します。現在トランザクションが存在する場合、現在のトランザクションは一時停止されます。
  5. PROPAGATION_NESTED: 現在トランザクションが存在する場合は、ネストされたトランザクション内で実行されます。現在トランザクションが存在しない場合は、REQUIRED 属性に従って実行されます。
  6. PROPAGATION_MANDATORY: トランザクションが現在存在する場合はトランザクションに参加し、現在トランザクションが存在しない場合は例外をスローします。
  7. PROPAGATION_NEVER: 非トランザクション方式で実行し、トランザクションが現在存在する場合は例外をスローします。

3. 春の隔離レベル:

  1. ISOLATION_DEFAULT: これは、データベースのデフォルトのトランザクション分離レベルを使用する、PlatfromTransactionManager のデフォルトの分離レベルです。
  2. ISOLATION_READ_UNCOMMITTED: コミットされていないデータを読み取り、トランザクションが実行中に他のトランザクションからコミットされていないデータを読み取ることができるようにします。
  3. ISOLATION_READ_COMMITTED: 読み取りがコミットされ、トランザクションは実行中に他のトランザクションによって送信されたデータを読み取ることができます。
  4. ISOLATION_REPEATABLE_READ: 同じトランザクション内での反復可能な読み取り。クエリ結果はいつでも一貫しています。
  5. ISOLATION_SERIALIZABLE: すべてのトランザクションは 1 つずつ実行されます。

10. Spring Beanの範囲

  1. singleton: デフォルトのスコープ、シングルトン Bean。各コンテナには Bean インスタンスが 1 つだけあります。

  2. プロトタイプ: Bean リクエストごとにインスタンスを作成します。

  3. request: 各リクエストのインスタンスを作成します。リクエストが完了すると、Bean は期限切れになり、ガベージ コレクターによってリサイクルされます。

  4. セッション: リクエスト スコープと同様に、同じセッションがインスタンスを共有し、異なるセッションは異なるインスタンスを使用します。

  5. global-session: グローバル スコープ。すべてのセッションが 1 つのインスタンスを共有します。すべてのセッションで共有されるストレージ変数を宣言する場合は、グローバル変数を global-session に格納する必要があります。


おすすめ

転載: blog.csdn.net/qq_45867699/article/details/129912105