ホームページ >Java >&#&チュートリアル >SpringAOP の理解
AOP (アスペクト指向プログラミング) は、オブジェクト指向プログラミングの補足として、トランザクション管理、セキュリティ チェック、キャッシュ、オブジェクト プール管理など、横断的なプロパティを持ついくつかのシステム レベルのサービスを処理するために広く使用されています。 AOP 実装の鍵は、AOP フレームワークによって自動的に作成される AOP プロキシにあります。AOP プロキシは、静的プロキシと動的プロキシの 2 つのカテゴリに分類されます。 AOP プロキシ クラスはコンパイル時拡張とも呼ばれますが、動的プロキシは JDK 動的プロキシ、CGLIB などを使用して実行時に AOP 動的プロキシ クラスをメモリ内に生成します。ランタイム拡張とも呼ばれます。
AOPの存在価値
従来のOOPプログラミングでは、オブジェクトが核となり、相互に依存する一連のオブジェクトでソフトウェアシステム全体が構成され、これらのオブジェクトは一つずつクラスに抽象化され、クラスの継承が許可されます。クラスとの一般的な関係から特定の関係までを管理するために使用されます。ソフトウェアの規模が大きくなり、アプリケーションが徐々にアップグレードされると、OOP では解決するのが難しい問題が徐々に現れます。
特定の属性と動作を持つ一連のオブジェクトを分析および抽象化し、これらのオブジェクト間のコラボレーションを通じて完全なソフトウェア機能を形成できます。オブジェクトは継承できるため、同じ機能や特性を持つ属性を階層的なクラス構造システムに抽象化できます。ソフトウェア仕様の継続的な拡張、専門分業の増加、OOP アプリケーションの実践数の増加に伴い、OOP ではうまく解決できない問題もいくつか明らかになってきています。
ここで、システム内にまったく同じコードが 3 つあるとします。これらのコードは通常、「コピー」と「貼り付け」によって完成します。この「コピー」と「貼り付け」方法で開発されたソフトウェアを図 1 に示します。
図 1. 複数の場所に同じコードを含むソフトウェア
図 1 に示す概略図を見て、このアプローチの欠点に気づいた読者もいるかもしれません。変更するにはコードを 3 か所開く必要がありますか?このコードが 3 か所ではなく 100 か所、さらには 1,000 か所に含まれていた場合はどうなるでしょうか?
この問題を解決するには、通常、図 1 に示すようなダーク コード部分をメソッドとして定義し、そのメソッドを 3 つのコード セグメントでそれぞれ呼び出します。このようにしてソフトウェアシステムの構成を図2に示します。
図 2 メソッド呼び出しによるシステム関数の実装
図 2 に示すソフトウェア システムの場合、暗い部分のコードを変更する必要がある場合は、コード内に何箇所あっても、1 か所だけを変更するだけで済みます。システム全体が呼び出されます。このメソッドを使用すると、プログラムはこれらの場所を変更する必要はなく、呼び出されたメソッドを変更するだけで済みます。このようにして、後のソフトウェアのメンテナンスの複雑さが大幅に軽減されます。
図 2 に示すメソッド 1、メソッド 2、およびメソッド 3 の場合でも、ほとんどのアプリケーション シナリオを解決できるダーク メソッドを明示的に呼び出す必要があります。ただし、より特殊な場合: アプリケーションは、メソッド 1、メソッド 2、およびメソッド 3 をダーク メソッドから完全に分離する必要があります。メソッド 1、メソッド 2、およびメソッド 3 は、ダーク メソッドを直接呼び出す必要はありません。解決しますか?
ソフトウェアのシステム要件は非常に頻繁に変化するため、初期段階ではメソッド 1、メソッド 2、およびメソッド 3 を設計するときに、システムにはコア ビジネス機能のみが実装されました。しばらくすると、メソッド 1、メソッド 2、およびメソッドのトランザクションを追加する必要があります。 3. コントロール。しばらくすると、顧客は方法 1、方法 2、および方法 3 を提案しました。これらの方法は、正規のユーザーのみが実行できるようになります。および方法 3。 3 ログ レコードを追加する必要があります。しばらくして、顧客から再度質問されました。このような状況に直面した場合はどうすればよいですか?通常、次の 2 つのアプローチがあります:
需要仕様に基づいて顧客のリクエストを直接拒否します。
ニーズを受け入れ、顧客のニーズに応えます。
最初のアプローチは明らかに良くありません。顧客は神であり、私たちは顧客のニーズに応えるために最善を尽くすべきです。通常は 2 番目のアプローチが採用されますが、どのように解決すればよいでしょうか?最初に新しいメソッドを定義し、次にメソッド 1、メソッド 2、およびメソッド 3 を変更し、呼び出す新しいメソッドを追加しますか?これを行うための作業負荷は小さくありません。特別なメソッドが必要です。このメソッドを定義している限り、メソッド 1、メソッド 2、およびメソッド 3 で明示的に呼び出す必要はありません。システムはこの特別なメソッドを「自動的に」実行します。
上記のアイデアは魔法のように聞こえ、少し非現実的ですらありますが、実際には、この要件を達成するためのテクノロジーは AOP です。 AOP は、特にシステム内のさまざまなモジュール (さまざまなメソッド) に分散されている相互関係の問題に対処するために使用されます。Java EE アプリケーションでは、トランザクション管理やセキュリティ チェックなど、いくつかの横断的なシステム レベルのサービスを処理するためによく使用されます。 、キャッシュ、オブジェクト プール管理など、AOP は非常に一般的なソリューションになりました。
Spring AOP 原理分析
前の紹介からわかるように、AOP プロキシは実際には AOP フレームワークによって動的に生成されるオブジェクトであり、ターゲット オブジェクトとして使用できます。 AOP プロキシにはターゲット オブジェクトのすべてのメソッドが含まれていますが、AOP プロキシ内のメソッドはターゲット オブジェクトのメソッドとは異なります。AOP メソッドは、特定のエントリ ポイントで拡張処理を追加し、ターゲット オブジェクトのメソッドをコールバックします。
AOP プロキシに含まれるメソッドとターゲット オブジェクトのメソッド図を図 3 に示します。
図 3. AOP プロキシ メソッドとターゲット オブジェクト メソッド
Spring の AOP プロキシは Spring の IoC コンテナによって生成および管理され、その依存関係も IoC コンテナによって管理されます。したがって、AOP プロキシはコンテナ内の他の Bean インスタンスを直接ターゲットにすることができ、これは IoC コンテナの依存関係注入によって提供される関係です。
AOP プログラミングを見ると、プログラマーの参加が必要な部分は 3 つだけです:
共通のビジネス コンポーネントの定義。
エントリ ポイントを定義します。1 つのエントリ ポイントが複数のビジネス コンポーネントにまたがる場合があります。
拡張処理を定義します。これは、通常のビジネス コンポーネントの AOP フレームワークに組み込まれた処理アクションです。
上記の 3 つの部分のうち、最初の部分は最も一般的なものであり、追加の説明は必要ありません。 AOP プログラミングの鍵となるのは、エントリ ポイントを定義し、拡張処理を定義することです。適切なエントリ ポイントと拡張処理が定義されると、AOP フレームワークは AOP プロキシを自動的に生成します。AOP プロキシのメソッドは大まかに次の式になります:
プロキシ オブジェクトのメソッド = 拡張処理 + のメソッドプロキシ オブジェクト
上記のビジネス定義では、Spring AOP の実装原理が実際には非常に単純であることを見つけるのは難しくありません。AOP フレームワークは、AOP プロキシ クラスとこのプロキシ クラスのメソッドを動的に生成する責任があります。ターゲットオブジェクトのアドバイスメソッドとコールバックメソッドで構成されます。
前述の図 2 に示すソフトウェア呼び出し構造の場合: メソッド 1、メソッド 2、メソッド 3... すべてが「横断的」プロパティを持つメソッドを呼び出す必要がある場合、従来のアプローチはプログラマーがメソッドを手動で変更することです。 1、メソッド 2、メソッド 3... この「横断的」メソッドをコードから呼び出す方法ですが、このアプローチではコードを毎回変更する必要があるため、スケーラビリティが劣ります。
そこで、AOP フレームワークが登場しました。AOP フレームワークは新しいプロキシ クラスを「動的に」生成でき、このプロキシ クラスに含まれるメソッド 1、メソッド 2、およびメソッド 3 には、この「横断的な」プロパティを呼び出す機能も追加されます。メソッド - ただし、この呼び出しは AOP フレームワークによって自動的に生成されるプロキシ クラスによって処理されるため、優れたスケーラビリティを備えています。プログラマは、メソッド 1、メソッド 2、およびメソッド 3 のコードを手動で変更する必要はありません。プログラマは、エントリ ポイントを定義するだけで済みます。AOP フレームワークによって生成された AOP プロキシ クラスには、新しいメソッド 1、アクセス メソッド 2、およびメソッド 3 が含まれています。 AOP フレームワークは、エントリ ポイントに基づいて、メソッド 1、メソッド 2、およびメソッド 3 の「横断的」プロパティを持つメソッドをコールバックするかどうかを決定します。
要するに: AOP 原理の秘密は、図 2 の呼び出しを実装するプロキシ クラスを動的に生成することです。この呼び出しでは、プログラマがコードを変更する必要はありません。
概要
AOP は、横断的なプロパティを持つ一部のシステムレベルのサービスを処理するために広く使用されています。AOP の出現は OOP を補完するものであり、開発者は横断的なプロパティを持つサービスをよりエレガントな方法で処理できるようになります。 AspectJ であろうと Spring AOP であろうと、どのような種類の AOP 実装であっても、それらはすべて AOP プロキシ クラスを動的に生成する必要があります。唯一の違いは、AOP プロキシ クラスを生成するタイミングです。AspectJ はコンパイル時に AOP プロキシ クラスを生成します。そのため、パフォーマンスは向上しますが、処理には特定のコンパイラを使用する必要があります。Spring AOP はランタイムを使用して AOP プロキシ クラスを生成するため、処理に特定のコンパイラを使用する必要はありません。 Spring AOP は実行のたびに AOP プロキシを生成する必要があるため、パフォーマンスが若干低下します。
SpringAOP の理解に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。