Why we use Dynamic Proxy

2020-06-18 05:06发布

问题:

A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface. It can be used to create a type-safe proxy object for a list of interfaces without requiring pre-generation of the proxy class.Dynamic proxy classes are useful to an application or library that needs to provide type-safe reflective dispatch of invocations on objects that present interface APIs

Above picture is good sample but Why we use dynamic proxy?

Is there any a simple example that use in real world,for more perception?

回答1:

This link describe dynamic proxy in code:

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;  
    }  
}  


回答2:

A common use-case is for Aspect-Oriented Programming, in which you seek to apply common functionality across a number of components without requiring the components themselves to implement the functionality. In these cases you can use a dynamic proxy to wrap all targeting components with additional behavior. Doing so

A couple examples:

  • ORMs such as Hibernate and Entity Framework do this to provide a persistence implementation around a code-first design. The core domain classes are built without any knowledge of their persistence, and the frameworks either wrap or extend these classes at startup to handle the actual implementation.

  • Wrapping all members of an interface with an aspect such as logging, or caching. For example, if you want to log every method call on ISomeInterface you could write a dynamic proxy which finds all interface methods, calls a Log method with the method details, and then passes the call to the actual implementation.



回答3:

Imagine you have two objects Car and Motorboat that implement interfaces CanDrive and CanFloat respectively. Now, you want to have a third object that implements both of those interfaces and that reuses logic from Car and Motorboat. In languages like Groovy, Ruby and Scala you could solve that by using mixin. In Java, however, there is no such thing. You could of course use e.g. Adapter design pattern, but in many cases (especially when building frameworks) the dynamic proxy come in useful. Consider the example that uses cglib library:

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());


回答4:

You should checkout this excellent article:
http://www.ibm.com/developerworks/java/library/j-jtp08305/index.html



标签: c# java proxy