1。エージェントモード
プロキシモデルは英語でのプロキシまたはサロゲートと呼ばれ、どちらも中国語で「エージェント」として翻訳できます。いわゆるプロキシとは、ある人または機関が別の人または別の機関に代わって行動を起こすことを意味します。場合によっては、クライアントがオブジェクトを必要としないか、直接参照することはできず、プロキシオブジェクトはクライアントとターゲットオブジェクトの間の仲介者として機能することができます。
トランザクションの実行プロセスを単純にシミュレートすることにより、さまざまなエージェント間の違いを説明する
1.1静的プロキシ
ソースコードは、プログラマーによって作成されるか、特定のツールによって自動的に生成されてからコンパイルされます。プログラムが実行される前に、プロキシクラスの.classファイルは既に存在します。
パブリックインターフェイスpersondao {void savesers();}パブリッククラスPersonDaoimplはpersondaoを実装します{@Override public void saveperson(){system.out.println( "save person"); }}パブリッククラストランザクション{void begintransaction(){system.out.println( "transaction"); } void commit(){system.out.println( "commit"); }}次に、静的プロキシクラスを書きます--- PersonDaoインターフェイスを実装します
/*** static proxy class* @author qjc*/public class persondaoproxyはpersondao {persondao persondao;トランザクショントランザクション; public persondaoproxy(persondao persondao、トランザクショントランザクション){this.persondao = persondao; this.transaction = transaction; } @Override public void saveerson(){this.transaction.begintransaction(); this.persondao.saveperson(); this.transaction.commit(); }}テスト
/*** static proxyをテスト* @author qjc*/public class testpersonproxy {@test public void testsave(){persondao persondao = new persondaoimpl();トランザクショントランザクション= new Transaction(); persondaoproxy proxy = new persondaoproxy(persondao、取引); proxy.saveperson(); }}要約:
1.静的プロキシモードは、トランザクションを再利用しません
2. 100のクラスと100のプロキシがあるとします。インターフェイスにはいくつのメソッドがありますか、プロキシ層に実装する必要がある方法の数、およびいくつのトランザクションを開いて、多くの方法を提出する必要があります。
3.プロキシが複数のインターフェイスを実装する場合、インターフェイスのいずれかが変更された場合(メソッドが追加されます)、プロキシもそれに応じて変更する必要があります。
1.2 JDKダイナミックプロキシ
動的プロキシクラス:プログラムが実行されているときに反射メカニズムを使用して動的に作成されます。
JDKの動的プロキシは、4つの条件を満たす必要があります。1。ターゲットインターフェイス2。ターゲットクラス3。インターセプター4。プロキシクラス
PersonDaoインターフェイス、PersonDaoImplクラス、およびトランザクションクラスを使用して、前の例で
インターセプターを書きます
Java.lang.Reflect.InvocationHandler; Import Java.lang.Reflect.Method;/** * Interceptor * 1。 * 2にターゲットクラスをインポート * 2にインポートします。 //ターゲットクラスのプライベートトランザクショントランザクション。パブリックインターセプター(オブジェクトターゲット、トランザクショントランザクション){this.target =ターゲット; this.transaction = transaction; } / *** @paramプロキシターゲットオブジェクトのプロキシクラスのインスタンス* @paramメソッドプロキシインスタンスのインターフェイスメソッドを呼び出すメソッドインスタンス* @paramは、プロキシインスタンスのメソッドパラメーター値に渡されたオブジェクトアレイをagrayに渡す* @returnのメソッドパラメーター値に渡されます。 Throws throws {string methodname = method.getName(); if( "saveperson" .equals(methodname)|| "deleteperson" .equals(methodname)|| "updateperson" .equals(methodname)){this.transaction.begintransaction(); //トランザクションmethod.invoke(ターゲット)を有効にする; //ターゲットメソッドthis.transaction.commit()を呼び出します。 //トランザクションを送信} else {method.invoke(ターゲット); } nullを返します。 }}テスト
/*** JDKダイナミックプロキシ* @Author QJC*/public class testJDKProxy {@Test public void testsave(){/*** 1。ターゲットオブジェクトを作成* 2。トランザクショントランザクション= new Transaction();インターセプターインターセプター=新しいインターセプター(ターゲット、トランザクション); /***パラメーター1:コードで使用されるクラスローダーを設定します。これは、通常、ターゲットクラスと同じクラスローダーを使用します*パラメーター2:プロキシクラスによって実装されたインターフェイスを設定し、ターゲットクラスと同じインターフェイスを使用します*パラメーター3:コールバックオブジェクトを設定します。プロキシオブジェクトのメソッドが呼び出されると、指定されたオブジェクトの呼び出し方式が*/ persondao persondao =(persondao)proxy.newproxyinstance(target.getClass()。getClassolass()、target.getClass()。 persondao.saveperson(); }}要約:
1. JDKProxyによって生成されたプロキシクラスがインターフェイスを実装するため、ターゲットクラスのすべてのメソッドはプロキシクラスに含まれています。
2。生成されたプロキシクラスのすべての方法ターゲットクラスのすべてのメソッドをインターセプトします。インターセプターのInvokeメソッドの内容は、プロキシクラスの各メソッドの構成です。
3. JDKProxyを使用するときは、インターフェイスが存在する必要があります。
4. Invokeメソッドの3つのパラメーターは、呼び出されたメソッドのAPI、呼び出されたメソッドのパラメーター、およびターゲットクラスの呼び出されたメソッドの戻りタイプにアクセスできます。
欠点:
1。ターゲットオブジェクトのターゲットメソッドを呼び出すことを除き、インターセプターでは、関数は比較的単一です。この例では、トランザクションのみを処理できます。
2.インターセプターのInvokeメソッドの判断声明は、実際の開発環境では信頼できません。
1.3 CGLIBダイナミックプロキシ
PersonDaoImplクラスとトランザクションクラスを使用して、前の例で(インターフェイスなし)
インターセプタークラスを作成します
Net.sf.cglib.proxy.enhancer; Import net.sf.cglib.proxy.methodInterceptor; Import net.sf.cglib.proxy.methodproxy;/*** cglib proxy interceptor* @author qjc*/cglib proxy interceptor* @author qjc*/public class emptoreptor emptoreptor emptoreptor emptiriceplentic //プロキシターゲットクラスのプライベートトランザクショントランザクション。パブリックインターセプター(オブジェクトターゲット、トランザクショントランザクション){this.target =ターゲット; this.transaction = transaction; } / ** *ターゲットオブジェクトのプロキシオブジェクトを作成 * * @return * / public object createproxy(){// code enfancement enthancer enthancer = new Enhancer(); //このクラスは、プロキシオブジェクトEnhancer.setCallback(this)を生成するために使用されます。 //パラメーターはインターセプターenthancer.setsuperclass(target.getClass()); //プロキシオブジェクトを作成}/ *** @Param objターゲットオブジェクトのインスタンスプロキシクラスのインスタンス* @paramメソッドメソッドインスタンスプロキシインスタンスの親クラスメソッドを呼び出す* @paramは、プロキシインスタンスのパラメーター値に渡されたメソッドパラメーター値に渡されたオブジェクトの配列* @param methodproxyを使用します* @retturn edicableを使用します。メソッド、オブジェクト[] args、methodproxy methodproxy)throws throwable {this.transaction.begintransaction(); method.invoke(ターゲット); this.transaction.commit(); nullを返します。 }}テスト
/*** test cglibダイナミックプロキシ* cglibを介して生成されたプロキシオブジェクトは、ターゲットクラスのサブクラスです* @author qjc*/public class testcglibproxy {@test public void testsave(){object target = new persondaoimpl();トランザクショントランザクション= new Transaction();インターセプターインターセプター=新しいインターセプター(ターゲット、トランザクション); persondaoimpl persondaoimpl =(persondaoimpl)interceptor.createproxy(); persondaoimpl.saveperson(); }}要約:
1。CGLIBは、強力で高性能で高品質のコード生成クラスライブラリです。 Javaクラスを拡張し、ランタイム中にJavaインターフェイスを実装できます。
2. CGLIBを使用して、ターゲットクラスのサブクラスとしてプロキシクラスを生成します。
3.CGLIBを使用してプロキシクラスを生成するためにインターフェイスは必要ありません
4. CGLIBによって生成されたプロキシクラスは、親クラスのメソッドを上書きします。
5.インターセプター内のインターセプトメソッドの内容は、プロキシクラスのメソッドボディCGLIBとJDKダイナミックプロキシの違いです。
JDK:
ターゲットクラスとプロキシクラスが共通インターフェイスを実装します
インターセプターはInvocationHandlerインターフェイスを実装する必要があり、このインターフェイスのInvokeメソッド本体の内容は、プロキシオブジェクトメソッドボディのコンテンツです。
cglib:
ターゲットクラスはプロキシクラスの親クラスです
インターセプターはMethodEnterceptorインターフェイスを実装する必要があり、インターフェイス内のインターセプトメソッドはプロキシクラスのメソッドボディであり、バイトコード強化メカニズムを使用してプロキシオブジェクトを作成します。
2。指向プログラミング
OOP(オブジェクト指向プログラミング):カプセル化、継承、多型、抽象化
コードのカプセル化、基本的およびモジュール管理。各クラスには独自の機能がある場合があります。何かがうまくいかない場合は、問題について話し合う人を探してください。修正の観点からは、コードを直接変更するとリスクが高い場合があります。これは長期的な解決策ではありません。最も自然なことは、タイプのカプセル化から変更することです。ただし、新しいタイプと古いシステムを統合する方法であるため、クラス間の血液関係を確立する必要があります。次に、これが継承の要件です。継承を通じて、これらのクラスは関連しており、それらの間に父と息子の関係があることがわかります。次に、継承に基づいて、多型には決定的な特性があります。したがって、一般に、オブジェクト指向の最もコアの特徴は実際には多型であると考えられています。最初の数人はすべて基礎を築いています。多型はそのコア機能です。サブクラスの書き換え方法は、このレベルの拡張を表し、古いシステムに統合でき、正常に機能することができます。これは、このレベル、新しい方法、古いシステム、拡張、再利用の再利用です。
AOP(セクション指向プログラミング):
Essential Programmingは、プリパル化されたランタイムダイナミックプロキシを介してソースコードを変更せずにプログラムに機能を動的に追加するテクノロジーです。
OOPとAOPの違い:
OOP:抽象カプセル化は、エンティティと、ビジネス処理プロセスのその特性と行動で実行され、論理ユニットのより明確な分割を取得します。
AOP:ビジネスプロセスで交差カットロジックを抽出します。ロジックプロセスの部分間の低カップリング分離効果を取得するために、プロセスの特定のステップまたは段階に直面します。これらの2つのデザインのアイデアには、目標に本質的な違いがあります。 AOPはコードブロックの再利用を達成しました。
スプリングAOPプロキシメカニズム:
1.ターゲットオブジェクトがいくつかのインターフェイスを実装する場合、SpringはJDKのJava.lang.Reflect.Proxyクラスプロキシを使用します。
利点:インターフェイスがあるため、システムはよりゆるく結合されています
短所:ターゲットクラスごとにインターフェイスを作成します
2.ターゲットオブジェクトがインターフェイスを実装していない場合、SpringはCGLIBライブラリを使用してターゲットオブジェクトのサブクラスを生成します。
利点:プロキシクラスとターゲットクラスが継承されているため、インターフェイスが存在する必要はありません。
短所:インターフェイスが使用されていないため、システムのカップリングはJDKを使用した動的プロキシほど良くありません。
PersonDaoインターフェイス、PersonDaoImplクラス、およびトランザクションクラスを使用します
スプリング構成を書き込みます
<bean id = "persondao"> </bean> <bean id = "transaction"> </bean> <aop:config> <! - ポイントカット式がターゲットクラスを決定します - > <aop:aop:pointcut expression = "execution(* cn.qjc.aop.xml.persondaoimpl。) <aop:aspect ref = "transaction"> <aop:method = "begintransaction" pointcut-ref = "forming"/> <aop:a after-returning method = "commit" pointcut-ref = "perform"/> </aop:aspect> </aop:config> </beans>
テスト
/***スプリングダイナミックプロキシ* @Author QJC*/public class transactionTest {@test public void testsave(){ApplicationContext Context = new ClassPathxMLApplicationContext( "CN/QJC/AOP/XML/APPLICATIONCONTEXT.XML"); persondao persondao =(persondao)context.getbean( "persondao"); persondao.saveperson(); }}スプリングAOPの原則
1.スプリング容器が起動すると、2台の豆が装填され、インスタンス化されます。
2。スプリングコンテナが構成ファイルを<aop:config>に解析する場合、ポイントカット式を解析し、ポイントカット式に従ってスプリングコンテナコンテンツの豆を一致させます。
3.試合が成功した場合は、Beanのプロキシオブジェクトを作成します
4.クライアントがcontext.getBeanを使用してオブジェクトを取得すると、オブジェクトにプロキシオブジェクトがある場合、プロキシオブジェクトが返されます。プロキシオブジェクトがない場合、オブジェクト自体を返します。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。