Java反射メカニズムと動的プロキシにより、Javaがより強力になります。 SpringのコアコンセプトIOCとAOPは、反射メカニズムと動的プロキシを通じて実装されます。
1 Java反射
例:
user user = new user(); user.settime5flag( "test"); class <? cls.getDeclaredMethod()を使用するか、アクセシビリティメソッドを変更するためにトラバースを実行します。文字列res1 =(string)method.invoke(user); system.out.println(res1); // intなどの基本的なタイプが含まれている場合は、int.classを使用してください! integer.class!= int.class! method = cls.getMethod( "settime5flag"、string.class); Method.Invoke(user、 "Rollen"); method = cls.getMethod( "getTime5Flag"); string res2 =(string)method.invoke(user); system.out.println(res2);
オブジェクトを介して完全なパッケージとクラス名を取得します。
user.getClass()。getName(); //フルパスクラス名user.getClass()。getSimplename(); //パッケージ名なしのクラス名
クラスを取得:
class.forname( "com.test.user"); com.test.user.class; user.getClass();クラスからオブジェクトをインスタンス化します
ユーザーユーザー=(ユーザー)cls.newinstance(); //パラメーターコンストラクターが必要ですすべてのコンストラクターを取得します
constructor <?> cons [] = cls.getConstructors(); // const [0] .newinstance()を宣言順序で返します。 //ディスプレイ宣言なしで、デフォルトのコンストラクターがありますクラスによって実装されたすべてのインターフェイスを取得します
class <?> intes [] = cls.getInterfaces();親クラスを取得します
cls.getsuperclass();修飾子を取得します
int mo = cls.getModifiers(); int mo = cons [0] .getModifiers(); int mo = method.getModifiers(); modifier.toString(mo);メソッドパラメーターを取得します
method.getParameters(); cons [0] .getParameters();メソッドパラメータータイプを取得します
method.getParametortypes(); cons [0] .getParametortypes();メソッド宣言によってスローされるすべての例外タイプを取得します
method.getExceptionTypes();このクラスで宣言されたすべてのプロパティを取得します
field [] field = cls.getdeclaredfields(); // privatefield [0] .getModifiers(); field [0] .getType();
親クラスの宣言、インターフェイス宣言、およびこのクラス宣言のすべての公的属性を含む、このクラスのすべての公的属性を取得します
cls.getfields();
指定された属性をアクセスに設定します
field.setAccessible(true); field.set(obj、 'ces'); field.get(obj);
* getFields()とgetDeclaredFields()の違い:getFields()は、クラスで公開されていると宣言されたフィールドのみにアクセスできます。プライベートフィールドにアクセスすることはできず、他のクラスから継承されたパブリックフィールドにアクセスできます。 getDeclaredFields()は、クラス内のすべてのフィールドにアクセスできます。これは、パブリック、プライベート、保護とは関係ありませんが、他のクラスから継承されたフィールドにアクセスできません。
* getMethods()とgetDeclaredMethods()の違い:getMethods()は、クラスでパブリックとして宣言された方法のみにアクセスでき、プライベートメソッドにアクセスできず、他のクラスから継承されたパブリックメソッドにアクセスできます。 getDeclaredMethods()は、クラス内のすべてのフィールドにアクセスできます。これは、パブリック、プライベート、保護とは関係ありません。他のクラスから継承されたメソッドにアクセスできません。
* getConstructors()とgetDeclaredConstructors()の違い:getConstructors()は、クラスで公開されていると宣言されたコンストラクターのみにアクセスできます。 getDeclaredConstructors()は、クラス内のすべてのコンストラクターにアクセスでき、パブリック、プライベート、保護とは何の関係もありません。
リフレクションを通じて配列の情報を取得して変更します
int [] temp = {1,2,3,4,5}; class <? "+array.getLength(temp)); // 5System.out.println("配列の最初の要素: "+array.get(temp、0)); // 1array.set(temp、0、100); system.out.println("修正後の配列の最初の要素は: "+array.get(0);配列タイプを取得しますcls.getComponentType();配列タイプかどうかを判断します
cls.isarray();
2 Javaエージェント
プロキシモデルは、一般的に使用されるJava設計モデルです。その特徴は、プロキシクラスとデリゲートクラスが同じインターフェイスを持っていることです。プロキシクラスは、主にメッセージの前処理、メッセージのフィルタリング、デリゲートクラスへのメッセージの転送、およびイベント後のメッセージの処理を担当します。通常、プロキシクラスとデリゲートクラスの間には関連性があります。プロキシクラスのオブジェクトは、デリゲートクラスのオブジェクトに関連付けられています。プロキシクラス自体のオブジェクトは、本当にサービスを実装するのではなく、代表クラスオブジェクトの関連する方法を呼び出すことで特定のサービスを提供します。
エージェントの作成期間によると、エージェントクラスは2つのタイプに分けることができます。
•静的プロキシ:プログラマーによって作成されるか、特定のツールによってソースコードを自動的に生成してからコンパイルします。プログラムが実行される前に、プロキシクラスの.classファイルは既に存在します。
•動的プロキシ:プログラムが実行されているとき、BytecodeはJava反射メカニズムによって動的に生成されます。
2.1静的プロキシ
public interface count {public void querycount();} public class countimpl count count {public void querycount(){system.out.println( "view account method ..."); }} //プロキシクラスパブリッククラスCountProxy Count Count {private countimpl countimpl; public countProxy(Countimpl countimpl){this.countimpl = countimpl; } @Override public void querycount(){system.out.println( "トランザクション処理前"); Countimpl.QueryCount(); //デリゲートクラスメソッドを呼び出します。 System.out.println( "トランザクション処理後"); }} //テストクラスのパブリッククラスTestCount {public static void main(string [] args){countimpl countimpl = new countimpl(); CountProxy CountProxy = new CountProxy(Countimpl); CountProxy.QueryCount(); }}コードを観察し、各プロキシクラスが1つのインターフェイスのみを提供できることを確認してください。そうすれば、プログラム開発では必然的に多くのプロキシが発生するようにします。さらに、異なる呼び出し方法を除くすべてのプロキシ操作は、他のすべての操作が同じであるため、この時点でコードを繰り返す必要があります。この問題を解決する最良の方法は、プロキシクラスを通じてすべてのプロキシ関数を完了することです。そのため、現時点では動的プロキシを使用して行う必要があります。
2.2動的エージェント
ダイナミックプロキシクラスのバイトコードは、プログラマーがそのソースコードを手動で記述する必要なく、プログラムの実行時にJava反射メカニズムによって動的に生成されます。 Java反射メカニズムはあらゆるタイプの動的プロキシクラスを生成できるため、動的プロキシクラスはプログラミングを簡素化するだけでなく、ソフトウェアシステムのスケーラビリティを改善します。
2.2.1 JDKダイナミックプロキシ
java.lang.Refllectパッケージのプロキシクラスと[InvocationHandlerインターフェイス]は、動的プロキシクラスを生成する機能を提供します。
InvocationHandlerインターフェイス:
public interface rivocationhandler {
パブリックオブジェクトInvoke(Object Proxy、Method Method、Object [] args)スロー可能。
}
パラメーター説明:
オブジェクトプロキシ:プロキシ化されているオブジェクトを指します。
方法方法:呼び出される方法
Object [] args:メソッドを呼び出すときに必要なパラメーター
InvocationHandlerインターフェイスのサブクラスは、プロキシの最終操作クラスと考えることができ、ProxySubjectを置き換えます。
プロキシクラス:
プロキシクラスは、プロキシを専門とするオペレーションクラスです。このクラスを介して、1つ以上のインターフェイスの実装クラスを動的に生成できます。このクラスは、次の操作方法を提供します。
public staticオブジェクトNewProxyInstance(classloaderローダー、クラス<?
パラメーター説明:
クラスローダーローダー:クラスローダー
クラス<?> []インターフェイス:すべてのインターフェイスを取得します
InvocationHandler H:InvocationHandlerインターフェイスのサブクラスインスタンスを取得します
動的プロキシを完成させる場合は、最初に、Proxyの特定の操作を完了するために、InvocationHandlerインターフェイスのサブクラスを定義する必要があります。
interface subject {public string said(string name、int age);} class realsubject emplements subject {@override public string(string name、int age){return name + "" + age; }} // jdkダイナミックプロキシクラスmyInvocationhandlerを実装するrikocationhandler {private object target = null; //デリゲートオブジェクトをバインドし、プロキシクラスのパブリックオブジェクトバインド(オブジェクトターゲット)を返します{これ。ターゲット=ターゲット; proxy.newProxyInstance(target.getClass()。getClassLoader()、target.getClass()。getInterfaces()、this); //インターフェイスをバインドします(cglibはこれを補います)} @Override public object invoke(Object Proxy、Method Method、Object [] args)throws {system.out.println( "method!");オブジェクトtemp = method.invoke(ターゲット、args); system.out.println( "after method!"); return temp; }} class hello {public static void main(string [] args){myInvocationHandler demo = new MyInvocationHandler();件名sub =(subject)demo.bind(new realSubject());文字列info = sub.say( "rolen"、20); System.out.println(info); }}ただし、JDKの動的プロキシはインターフェイスの実装に依存しています。一部のクラスがインターフェイスを実装していない場合、JDKプロキシを使用できないため、CGLIBダイナミックプロキシを使用する必要があります。
2.2.2 cglibダイナミックプロキシ
JDKの動的プロキシメカニズムは、インターフェイスを実装するプロキシクラスのみを実行できますが、インターフェイスを実装しないクラスはJDKの動的プロキシを実装できません。
CGLIBはクラスのプロキシを実装します。その原則は、指定されたターゲットクラスのサブクラスを生成し、メソッド実装の強化をオーバーライドすることです。ただし、継承が使用されるため、最終的な修正クラスをプロキシ化することはできません。
public interface bookfacade {public void addbook(); } public class bookfacadeimpl1 {public void addbook(){system.out.println( "本を追加する通常の方法..."); }} import java.lang.Reflect.Method; net.sf.cglib.proxy.enhancerをインポートします。 net.sf.cglib.proxy.methodInterceptorをインポートします。 net.sf.cglib.proxy.methodproxyをインポートします。 // cglibダイナミックプロキシクラスパブリッククラスbookfacadecglibはmethodinterceptor {private object target; //デリゲートオブジェクトをバインドし、プロキシクラスのパブリックオブジェクトGetInstance(Object Target){this.target =ターゲット; Enhancer Enhancer = new Enhancer(); Enhancer.setsuperclass(this.target.getClass()); //コールバックメソッドEnhancer.setCallback(this); //プロキシオブジェクトを作成しますreturn enthancer.create(); } @Override //コールバックメソッドパブリックオブジェクトインターセプト(オブジェクトobj、メソッドメソッド、オブジェクト[] args、methodproxyプロキシ)スロー可能{system.out.println( "function start");オブジェクトTemp = proxy.invokesuper(obj、args); system.out.println( "関数end"); return temp; }} public class testcglib {public static void main(string [] args){bookfacadecglib cglib = new bookfacadecglib(); bookfacadeimpl1 bookcglib =(bookfacadeimpl1)cglib.getInstance(new bookfacadeimpl1()); bookcglib.addbook(); }}Java ReflectionとProxyに関する上記の簡単な議論は、私があなたと共有するすべてのコンテンツです。参照を提供できることを願っています。wulin.comをもっとサポートできることを願っています。