静态代理和动态代理

所谓代理,可以认为是 客户无法直接与服务端交流,那么就需要一个媒介来处理他们之间的会面。思想比较简单,但是遇到真实情况下,静态代理比较容易理解,动态代理值得学习,想起以前别人的一些程序还是比较容易理解。

一)静态代理

1:

public abstract class Subject
{
    public abstract void request();
}

2:

public class RealSubject extends Subject
{
    public void request()
    {
        System.out.println("From real subject.");
    }
}
:

3:

public class ProxySubject extends Subject
{
    private RealSubject realSubject; //代理角色内部引用了真实角色
    
    public void request()
    {
        this.preRequest(); //在真实角色操作之前所附加的操作
        
        if(null == realSubject)
        {
            realSubject = new RealSubject();
        }
        
        realSubject.request(); //真实角色所完成的事情
        
        this.postRequest(); //在真实角色操作之后所附加的操作
    }
    private void preRequest()
    {
        System.out.println("pre request");
    }
    
    private void postRequest()
    {
        System.out.println("post request");
    }
}

4:

public class Client
{
    public static void main(String[] args)
    {
        Subject subject = new ProxySubject();
        
        subject.request();
    }
}
二)动态代理

1:

public interface Subject
{
    public void request();
}


2:

public class RealSubject implements Subject
{
    public void request()
    {
        System.out.println("From real subject!");
    }

}

3:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象
 * 此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要
 * 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后
 * 加入自己的一些额外方法。
 *
 */

public class DynamicSubject implements InvocationHandler
{
    private Object sub;
    
    public DynamicSubject(Object obj)
    {
        this.sub = obj;
    }
    
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable
    {
        System.out.println("before calling: " + method);
        
        method.invoke(sub, args);
        
        System.out.println(args == null);
        
        System.out.println("after calling: " + method);
        
        return null;
    }
    

}

4:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Vector;

public class VectorProxy implements InvocationHandler
{
    private Object proxyObj;

    public VectorProxy(Object obj)
    {
        this.proxyObj = obj;
    }

    public static Object factory(Object obj)
    {
        Class<?> classType = obj.getClass();

        return Proxy.newProxyInstance(classType.getClassLoader(),
                classType.getInterfaces(), new VectorProxy(obj));
    }
    
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable
    {
        System.out.println("before calling: " + method);
        
        if(null != args)
        {
            for(Object obj : args)
            {
                System.out.println(obj);
            }
        }
        
        Object object = method.invoke(proxyObj, args);
        
        System.out.println("after calling: " + method);
        
        return object;
    }
    
    public static void main(String[] args)
    {
        List v = (List)factory(new Vector());
        
        System.out.println(v.getClass().getName());
        
        v.add("New");
        v.add("York");
        
        System.out.println(v);
        
        v.remove(0);
        System.out.println(v);
        
    }

}

5:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Client
{
    public static void main(String[] args)
    {
        RealSubject realSubject = new RealSubject();

        InvocationHandler handler = new DynamicSubject(realSubject);

        Class<?> classType = handler.getClass();

        // 下面的代码一次性生成代理

        Subject subject = (Subject) Proxy.newProxyInstance(classType
                .getClassLoader(), realSubject.getClass().getInterfaces(),
                handler);

        subject.request();

        System.out.println(subject.getClass());

    }

}

Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。

其实现主要通过是java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。可以这样想象:编译期间我们不知道有多少类,只有在运行期间利用反射机制动态的生成一些class。这就是所谓的动态代理,表面做到了灵活性,但是我始终觉得比较耗资源。


原文地址:https://www.cnblogs.com/MedivhQ/p/4074985.html