1。序文
以前のプロジェクトでは、Spring AOPの特定の実装と理論に注意を払うことはめったにありませんでした。 AOPとは何か、どのように使用するかを簡単に理解しました。よく書かれたブログ投稿を見たので、それを学ぶようになりました。
aop
AOP(アスペクト指向プログラミング)、つまりアスペクト指向プログラミングは、OOP(オブジェクト指向プログラミング)の補足と改善と言えます。 OOPは、カプセル化、継承、多型などの概念を導入して、公共行動のコレクションをシミュレートするために使用されるオブジェクト階層を確立します。ただし、OOPを使用すると、開発者は垂直関係を定義できますが、ロギング関数などの水平関係を定義するのに適していません。ログコードは、多くの場合、すべてのオブジェクトレベルで水平に散在しており、対応するオブジェクトのコア関数とは何の関係もありません。どこにでも散らばるこの種の無関係なコードは、クロス切断と呼ばれます。 OOP設計では、各モジュールの再利用を助長しない大量のコード複製を引き起こします。
それどころか、AOPテクノロジーは「CrossCutting」と呼ばれる手法を使用して、カプセル化されたオブジェクトの内部を分析し、複数のクラスに影響を与える一般的な動作を再利用可能なモジュールにカプセル化し、「Aspect」という名前の「アスペクト」と名付けます。いわゆる「セクション」は、ビジネスに関連するものではなく、ビジネスモジュールと共同で呼ばれる論理または責任によって単純にカプセル化されます。これは、システムの重複コードを削減し、モジュール間の結合を減らし、将来の運用性と保守性を促進するのに便利です。
「クロスカッティング」テクノロジーを使用して、AOPはソフトウェアシステムを2つの部分に分割します。コアの懸念と相互カットの懸念です。ビジネス処理の主なプロセスは中心的な焦点であり、それとはほとんど関係がない部分は横断的な焦点です。クロスカットの懸念の1つの特徴は、それらがしばしば複数のコアの懸念で発生することであり、基本的に許可認証、ログ、物などのさまざまな場所で類似していることです。 AOPの役割は、システム内のさまざまな懸念を分離し、中核的な懸念を相互習得の懸念から分離することです。
AOPコアコンセプト
1。クロスカットの注意点
どの方法を傍受する方法と傍受後に対処する方法は?これらの懸念は、相互に訴える懸念と呼ばれます
2。セクション(アスペクト)
クラスはオブジェクトの特徴の抽象化であり、セクションは相互に懸念の抽象化です
3。JoinPoint
スプリングはメソッドタイプの接続ポイントのみをサポートするため、springの接続ポイントは傍受されたメソッドを指します。実際、接続ポイントはフィールドまたはコンストラクターでもあります。
4。ポイントカット
接続ポイントの傍受の定義
5。通知(アドバイス)
いわゆる通知とは、接続ポイントを傍受した後に実行されるコードを指します。通知は、プリセット、ポストセット、例外、最終、および周囲の通知の5つのカテゴリに分けられます。
6。ターゲットオブジェクト
プロキシのターゲットオブジェクト
7。織り
ターゲットオブジェクトにスリットを適用し、プロキシオブジェクトの作成を引き起こすプロセス
8。はじめに
コードを変更せずに、導入は実行時間中にいくつかの方法またはフィールドをクラスに動的に追加できます
AOPに対するSpringのサポート
春のAOPエージェントは、SpringのIOCコンテナの生成と管理を担当し、その依存関係もIOCコンテナによって管理されます。したがって、AOPプロキシはコンテナ内の他のBeanインスタンスを直接ターゲットにでき、この関係はIOCコンテナの依存噴射によって提供できます。春にプロキシを作成するためのルールは次のとおりです。
1.デフォルトでは、Java Dynamic Proxyを使用してAOPプロキシを作成するため、任意のインターフェイスインスタンスのプロキシを作成できます。
2.プロキシを必要とするクラスがプロキシインターフェイスではない場合、SpringはCGLIBプロキシの使用に切り替わり、CGLIBを使用することもできます。
AOPプログラミングは実際には非常に簡単なものです。 AOPプログラミングを見ると、プログラマーは3つの部分に参加する必要があります。
1.通常のビジネスコンポーネントを定義します
2。エントリポイントを定義し、1つのエントリポイントが複数のビジネスコンポーネントをクロスカットする場合があります
3.強化された処理を定義します。強化された処理とは、AOPフレームワークの通常のビジネスコンポーネントに織り込まれた処理アクションです。
したがって、AOPプログラミングの鍵は、エントリポイントを定義し、強化処理を定義することです。適切なエントリポイントと拡張処理が定義されると、AOPフレームワークはAOPプロキシ、つまりプロキシオブジェクトの方法=拡張処理 +プロキシオブジェクトの方法を自動的に生成します。
これは、aop.xmlという名前のスプリングaop .xmlファイルテンプレートです。その後のコンテンツはaop.xmlで展開されます。
<?xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx = "http://www.springframework.org/schema/tx" xsi:schemalocation = "http://ww.springframework http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> </beans>
スプリングに基づくAOPの簡単な実装
説明する前に、説明しましょう。コードを正常に実行するには、Springが提供するJARパッケージを開発者に使用するだけでは不十分です。オンラインで2つのJARパッケージをダウンロードしてください:
1。Aopalliance.jar
2。aspectjweaver.jar
Spring AOPのXML実装方法の説明を始めましょう。最初にインターフェイスを定義します。
パブリックインターフェイスHelloworld {void printhelloword(); void doprint();} 2つのインターフェイス実装クラスを定義します。
パブリッククラスHelloworldimpl1はHelloworld {public void printhellowld(){system.out.println( "helloworldimpl1.printhelloword()"); } public void doprint(){system.out.println( "helloworldimpl1.doprint()");戻る ; }}パブリッククラスHelloworldimpl2はHelloworld {public void printhellowld(){system.out.println( "helloworldimpl2.printhelloword()"); } public void doprint(){system.out.println( "helloworldimpl2.doprint()");戻る ; }}クロスカットの焦点、ここに印刷時間があります:
public class timehandler {public void printtime(){system.out.println( "currenttime =" + system.currenttimemillis()); }}これらの3つのクラスを使用すると、Simple Spring AOPを実装できます。 aop.xmlの構成を見てください:
<?xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx = "http://www.springframework.org/schema/tx" xsi:schemalocation = "http://ww.springframework http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id =" helloworldimpl1 "/> <bean id =" helloworldimpl2 "/>> <bean id =" timehandler "/> <aop:pointcut id = "addallmethod" expression = "execution(* com.xrq.aop.hellowld。*(..)" /> <aop:method = "printtime" point-cut-ref = "addallmethod" /> <aop:after method = "printtime" point-cut-ref = "addallmethod"
それを呼び出すために主な関数を書きます:
public static void main(string [] args){applicationContext ctx = new classpathxmlapplicationContext( "aop.xml"); helloworld hw1 =(helloworld)ctx.getbean( "helloworldimpl1"); helloworld hw2 =(helloworld)ctx.getbean( "helloworldimpl2"); hw1.printhelloworld(); System.out.println(); hw1.doprint(); System.out.println(); System.out.println(); hw2.prinhelloworld(); System.out.println(); hw2.doprint();}実行中の結果は次のとおりです。
CurrentTime = 1446129611993ENTER HELLOWORLDIMPL1.PRINTHELLOWORLD()CurrentTime = 1446129611993CURRENTTIME = 14461296119994ENTER HELLOWORLDIMPL1.DOPRINT()CurrentTime = 144612961194CURRENTTIME = 1446112961994er helloworldimpl2.printhelloworld()currenttime = 1446129611994currenttime = 1446129611994enter helloworldimpl2.doprint()currenttime = 1446129611994
Helloworldインターフェイスの2つの実装クラスのすべての方法がプロキシに追加されており、プロキシコンテンツが印刷時間であることがわかりました。
SpringベースのAOP使用に関する追加の詳細
1.交差懸念を追加して、ログを印刷します。 Javaクラスは次のとおりです。
public class loghandler {public void logbebefore(){system.out.println( "log before method"); } public void logafter(){system.out.println( "log after method"); }}<?xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx = "http://www.springframework.org/schema/tx" xsi:schemalocation = "http://ww.springframework http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id =" helloworldimpl1 "/> <bean id =" ref = "TimeHandler" Order = "1"> <aop:pointcut id = "addtime" expression = "execution(* com.xrq.aop.hellowld。*(..)" /> <aop:method = "printtime" point-cut-ref = "addtime" /> <aop:after time "printtime" point-ref = " /aps" id = "log" ref = "loghandler" order = "2"> <aop:pointcut id = "printlog" expression = "execution(* com.xrq.aop.helloworld。*(..)" /> <aop:afther = "logbefore" pointcut-ref = "printlog" /> </aop:aspect> </aop:config> </beans>
テストクラスは変更されておらず、印刷の結果は次のとおりです。
CurrentTime = 1446130273734log Methodenter helloworldimpl1.printhelloworld()log abythercurrenttime = 1446130273735currenttime = 1446130273736log methoder helloworldimpl1.doprint() 1446130273736logメソジセンターの前のhelloworldimpl2.printhelloworld()log affery -currenttime = 1446130273736currenttime = 144613027373737log methodenter helloworldimpl2.doprint()log = 144613027373737737
タイムハンドラーの前にロガンドラーを使用する方法は2つあります。
(1)アスペクトには注文属性があり、注文属性の数はフォーカスポイントをクロスカットする順序です
(2)タイムハンドラーの前にロガンドラーを定義します。 Springは、デフォルトで織り順序としてアスペクトの定義順序を使用します。
2。インターフェイスにいくつかの方法を織りたいだけです
ポイントカット式を変更するだけです。
<?xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx = "http://www.springframework.org/schema/tx" xsi:schemalocation = "http://ww.springframework http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id =" helloworldimpl1 "/> <bean id =" ref = "timehandler" order = "1"> <aop:pointcut id = "addtime" expression = "execution(* com.xrq.aop.helloworld.print*(..)" /> <aop:method = "printtime" pintcut-ref = "addtime" /> <aop = "printtime" point-ref = "> id = "log" ref = "loghandler" order = "2"> <aop:pointcut id = "printlog" expression = "execution(* com.xrq.aop.helloworld.do*(..)" /> <aop:method = "logbe" point-cut-ref = "printlog" />> <"print" /> <"" print-ref = "print-ref = </aop:aspect> </aop:config> </beans>
つまり、タイムハンドラーはHelloworldインターフェイスプリントの開始時に始まる方法のみを織ります。Loghandlerは、Helloworldインターフェイスの始まりから始まる方法のみを織ります
3。プロキシを生成するようcglibを強制します
前述のように、Springは動的プロキシまたはCGLIBを使用してプロキシを生成します。 Springのより高いバージョンは、ダイナミックプロキシまたはCGLIBを使用してプロキシコンテンツを生成するかどうかを自動的に選択します。もちろん、CGLIBにプロキシを生成するように強制することもできます。つまり、<aop:config>には「プロキシターゲットクラス」属性があります。この属性値がtrueに設定されている場合、クラスベースのプロキシは機能します。プロキシターゲットクラスがfalseに設定されている場合、またはこの属性が省略されている場合、インターフェイスベースのプロキシが機能します。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。