6

動的プロキシクラスは、実行時に指定されたインターフェイスのリストを実装するクラスです。これにより、クラスのインスタンスのいずれかのインターフェイスを介したメソッド呼び出しがエンコードされ、統一インターフェイスを介して別のオブジェクトにディスパッチされます。プロキシ クラスの事前生成を必要とせずに、インターフェイスのリストのタイプ セーフなプロキシ オブジェクトを作成するために使用できます。インターフェイス API を提示する ここに画像の説明を入力

上の写真は良いサンプルですが、なぜ動的プロキシを使用するのでしょうか?

より多くの知覚のために、現実の世界で使用する簡単な例はありますか?

4

4 に答える 4

3

一般的な使用例は、アスペクト指向プログラミングです。この場合、コンポーネント自体に機能を実装する必要なく、多数のコンポーネントに共通の機能を適用しようとします。このような場合、動的プロキシを使用して、すべてのターゲティング コンポーネントを追加の動作でラップできます。そうする

いくつかの例:

  • Hibernate や Entity Framework などの ORM は、これを行って、コード ファーストの設計に関する永続的な実装を提供します。コア ドメイン クラスは永続性についての知識なしに構築され、フレームワークは起動時にこれらのクラスをラップまたは拡張して、実際の実装を処理します。

  • ロギングやキャッシングなどの側面でインターフェイスのすべてのメンバーをラップします。たとえば、ISomeInterface のすべてのメソッド呼び出しをログに記録する場合は、すべてのインターフェイス メソッドを検出し、メソッドの詳細を指定して Log メソッドを呼び出し、その呼び出しを実際の実装に渡す動的プロキシを作成できます。

于 2013-08-21T15:14:39.233 に答える
1

それぞれインターフェイス CanDrive と CanFloat を実装する 2 つのオブジェクト Car と Motorboat があるとします。ここで、これらのインターフェイスの両方を実装し、Car と Motorboat のロジックを再利用する 3 番目のオブジェクトが必要です。Groovy、Ruby、Scala などの言語では、mixin を使用してこれを解決できます。しかし、Java ではそのようなことはありません。もちろん、たとえば Adapter デザイン パターンを使用することもできますが、多くの場合 (特にフレームワークを構築する場合)、動的プロキシが役立ちます。cglib ライブラリを使用する例を考えてみましょう:

CanDrive car = new Car();
CanFloat motorboat = new Motorboat();

net.sf.cglib.proxy.Mixin amphibian = net.sf.cglib.proxy.Mixin.create(new Object[] { car, motorboat });

TestCase.assertEquals("bzzz bzzz bzzz ...", ((CanFloat) amphibian)._float());
TestCase.assertEquals("pyr pyr pyr pyr ...", ((CanDrive) amphibian).drive());
于 2013-08-21T15:35:45.997 に答える
0

このリンクでは、動的プロキシをコードで説明しています。

public static class DynamicProxyGenerator  
{  
    public static T GetInstanceFor<T>()  
    {  
        Type typeOfT = typeof(T);  
        var methodInfos = typeOfT.GetMethods();  
        AssemblyName assName = new AssemblyName("testAssembly");  
        var assBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assName, AssemblyBuilderAccess.RunAndSave);  
        var moduleBuilder = assBuilder.DefineDynamicModule("testModule", "test.dll");  
        var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "Proxy", TypeAttributes.Public);  

        typeBuilder.AddInterfaceImplementation(typeOfT);  
        var ctorBuilder = typeBuilder.DefineConstructor(  
                  MethodAttributes.Public,  
                  CallingConventions.Standard,  
                  new Type[] { });  
        var ilGenerator = ctorBuilder.GetILGenerator();  
        ilGenerator.EmitWriteLine("Creating Proxy instance");  
        ilGenerator.Emit(OpCodes.Ret);  
        foreach (var methodInfo in methodInfos)  
        {  
            var methodBuilder = typeBuilder.DefineMethod(  
                methodInfo.Name,  
                MethodAttributes.Public | MethodAttributes.Virtual,  
                methodInfo.ReturnType,  
                methodInfo.GetParameters().Select(p => p.GetType()).ToArray()  
                );  
            var methodILGen = methodBuilder.GetILGenerator();               
            if (methodInfo.ReturnType == typeof(void))  
            {  
                methodILGen.Emit(OpCodes.Ret);  
            }  
            else  
            {  
                if (methodInfo.ReturnType.IsValueType || methodInfo.ReturnType.IsEnum)  
                {  
                    MethodInfo getMethod = typeof(Activator).GetMethod(/span>"CreateInstance",new Type[]{typeof((Type)});                          
                    LocalBuilder lb = methodILGen.DeclareLocal(methodInfo.ReturnType);  
                    methodILGen.Emit(OpCodes.Ldtoken, lb.LocalType);  
                    methodILGen.Emit(OpCodes.Call, typeofype).GetMethod("GetTypeFromHandle"));  ));  
                    methodILGen.Emit(OpCodes.Callvirt, getMethod);  
                    methodILGen.Emit(OpCodes.Unbox_Any, lb.LocalType);  

                }  
                 else  
                {  
                    methodILGen.Emit(OpCodes.Ldnull);  
                }  
                methodILGen.Emit(OpCodes.Ret);  
            }  
            typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);  
        }  

        Type constructedType = typeBuilder.CreateType();  
        var instance = Activator.CreateInstance(constructedType);  
        return (T)instance;  
    }  
}  
于 2013-08-25T14:04:58.923 に答える
0

この優れた記事をチェックしてください:
http://www.ibm.com/developerworks/java/library/j-jtp08305/index.html

于 2013-08-22T20:49:55.593 に答える