この記事は、Javaの困難な問題についてです。 Javaコアライブラリを使用して、簡単なAOPメソッドを実装し、インスタンスコードを分析して比較します。以下はすべてコンテンツです:
春は非常に人気のあるオープンソースフレームワークであり、AOP(セクションプログラミング)は春の最も重要な概念の1つです。 AOPのアイデアをよりよく理解し、学ぶために、コアライブラリを使用して一度にそれを達成することは良い方法です。
まず、AOPの概念を紹介しましょう。 AOP(アスペクト指向プログラミング)、つまり接線指向プログラミング。いわゆる接線指向プログラミングは、横断面積の観点からコードを設計するという考えです。従来のOOPのアイデアは、カプセル化の継承と多型を使用して垂直階層関係を構築することですが、水平関係を定義するのに適していません。 AOPのアイデアは、これに良い補足を提供します。
たとえば、ログ管理コードは多くのオブジェクトレベルで水平に散在することがよくありますが、対応するオブジェクトのコア関数とは何の関係もありません。また、許可確認、デバッグ出力、トランザクション処理など、多くの同様のコードもありますが、これも同じです。これは、コードの再利用と管理を助長しません。
現時点では、AOPテクノロジーが生まれました。 「クロスカット」テクノロジーを使用して、カプセル化オブジェクトに深く浸透し、複数のクラスに影響を与える共通の動作を再利用可能なモジュールにカプセル化し、「アスペクト」、つまりスライスに名前を付けます。いわゆる「セクション」は、ビジネスに関連するものではなく、ビジネスモジュールと共同で呼ばれる論理または責任によって単純にカプセル化されます。これは、システムの重複コードを削減し、モジュール間の結合を減らし、その後の運用性と維持可能性を促進するのに便利です。
では、AOPはどのように実装されていますか?
答えは動的プロキシです(詳細についてはプロキシに関する別の章があるので、ここでは詳しく説明しません)。動的プロキシを実装するには2つの方法があります。1つはJDKダイナミックプロキシ、もう1つはCGLIB Dynamic Proxyです。
次に、2つの方法を使用して、シンプルな栗を作成します。
最初にシナリオを設計しましょう。コンピューティングインターフェイスイカル化装置と、このインターフェイスを実装する計算機クラスの計算機があるとします。
パブリックインターフェイスICALCulator {//追加操作public int add(int a、int b); //縮小public int suppract(int a、int b); //複数のpublic int Multiply(int a、int b); //配分public int define(int a、int b);}パブリッククラスCalculaturimplはICalculator {@Override public int add(int a、int b){return a + b; } @Override public int suppract(int a、int b){return a -b; } @Override public int Multiply(int a、int b){return a * b; } @Override public int define(int a、int b){return a / b; }}元の電卓クラスの内部コードを変更せずに計算機法の合計回数を記録する方法は?
動的プロキシを使用すると、実際には非常に簡単です。最初にクラスを作成し、InvocationHandlerインターフェイスを実装し、Invokeメソッドをオーバーライドします。
public class testhandlerを実装しているinvocationhandler {private object targetObject;プライベートイントアット。 //デリゲートオブジェクトをバインドし、プロキシクラスのパブリックオブジェクトバインド(Object TargetObject){this.targetObject =ターゲットオブジェクト; proxy.newProxyInstance(targetObject.getClass()。getClassLoader()、TargetObject.getClass()。getInterfaces()、this); } @OverrideパブリックオブジェクトInvoke(Object Proxy、Method Method、Object [] args)Throws Throwable {//(); Object result = method.invoke(ターゲットオブジェクト、args);後();返品結果; } private void before(){system.out.println( "計算前に何かをすることができます。"); } private void after(){usetimes ++; system.out.println( "使用:"+usetimes+"times"); }}コードが少し多すぎるようですが、主な方法はInvokeメソッドです。オブジェクトresult = method.invoke(targetobject、args);元のパラメーターを使用して元のメソッドを実行し続けることと同等です。ここの前後はカスタマイズされた関数です。これは、ここでの使用量など、オブジェクトコードが実行される前後にやりたいことを実行できます。
BINDメソッドでは、ターゲットプロキシオブジェクトが渡され、プロキシクラスインスタンスが返されます。次に、使用方法を見てみましょう。
public class testproxy {public static void main(string [] args){testhandler proxy = new testhandler(); icalculator calculate =(icalculator)proxy.bind(new calculaturimpl()); int result = calculate.add(1,2); system.out.println( "result is:"+result); result = calculate.subtract(3,2); system.out.println( "result is:"+result); result = calculater.multiply(4,6); system.out.println( "result is:"+result); result = calculater.devide(6,2); system.out.println( "result is:"+result); }}最初にテストハンドラーを定義し、次にBindメソッドを介してプロキシインスタンスを取得し、このインスタンスを直接使用できます。操作結果は次のとおりです。
計算する前に何かをすることができます。使用:1つの結果は次のとおりです。3WEは計算する前に何かをすることができます。使用:2つの結果は次のとおりです。1WEは計算する前に何かをすることができます。使用:3つの結果は次のとおりです。24私たちは計算する前に何かをすることができます。使用:4結果は次のとおりです
このようにして、CalculaturIMPLの内部コードを変更せずにコード拡張機能を実装します。
次に、CGLIBを使用して1回実装します。
最初にクラスを作成して、MethodEnterceptorインターフェイスを実装し、インターセプトメソッドをオーバーライドします。他のコードはJDKプロキシの使用に似ていますが、プロキシオブジェクトを取得するプロセスは異なります。
パブリッククラスcglibproxyはmethodinterceptor {private int usetimes;プライベートオブジェクトターゲット。 public object getInstance(Object Target){this.target =ターゲット; Enhancer Enhancer = new Enhancer(); Enhancer.setsuperclass(this.target.getClass()); Enhancer.setCallback(This); return enthancer.create(); } @Override public Object intercept(オブジェクトO、メソッドメソッド、オブジェクト[]オブジェクト、MethodProxy MethodProxy)スロー可能{before();オブジェクトresult = methodproxy.invokesuper(o、objects);後();返品結果; } private void before(){system.out.println( "計算前に何かをすることができます。"); } private void after(){usetimes ++; system.out.println( "使用:"+usetimes+"times"); }}それをテストする:
public class testcglibproxy {public static void main(string [] args){cglibproxy cglibproxy = new cglibproxy(); icalculator calculate =(icalculator)cglibproxy.getInstance(new calculaturimpl()); int result = calculate.add(1,2); system.out.println( "result is:"+result); result = calculate.subtract(3,2); system.out.println( "result is:"+result); result = calculate.multiply(4,6); system.out.println( "result is:"+result); result = calculate.devide(6,2); system.out.println( "result is:"+result); }}操作結果は次のとおりです。
計算する前に何かをすることができます。使用:1つの結果は次のとおりです。3WEは計算する前に何かをすることができます。使用:2つの結果は次のとおりです。1WEは計算する前に何かをすることができます。使用:3つの結果は次のとおりです。24私たちは計算する前に何かをすることができます。使用:4結果は次のとおりです
これで同じ結果が得られます。 (2つのパッケージが必要です。CGLIB-2.2.2.Jar ASM-3.3.Jar)
どちらの方法にも独自の強みがあります。 JDKプロキシは、プロキシを実装する前にインターフェイスを設定する必要があります。これがその欠点とその利点です。不利な点は、これがもう少し面倒であり、すでにカプセル化されている人をプロキシできず、インターフェイスを実装しないことです。 CGLIBプロキシメソッドは、インターフェイスの使用を必要としません。しかし、このために、JDKプロキシはクラス内のインターフェイスを上書きするメソッドのみをインターセプトし、CGLIBはクラスのすべてのメソッド呼び出しをインターセプトします。どちらにも長所と短所があるため、特定の状況を分析する必要があります。春には、2つのプロキシモードが混合されます。