首先声明,本为并非原创,大量参考自,一方面做个备份,另一方面也是自己学习的过程。

一、代理

对一个类(委托类,实际完成工作的那个类)方法的调用交给另一个类(代理类,可以静态或动态生成)来完成。如果委托类和代理类实现了同一个接口,那么代理就可以很方便的完成。

二、静态代理

程序运行前代理类和委托类的关系就已经确定,代理类的字节码文件已经存在,代理不是运行时生成。

Code list 1, 接口定义:

package proxy.staticy;public interface Subject {    void dealTask(String taskName);}

Code list 2,委托类,真正做事情的类:

package proxy.staticy;public class RealSubject implements Subject {    @Override    public void dealTask(String taskName) {        System.out.println("正在执行任务: " + taskName);        try {            Thread.sleep(500);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

Code list 3,代理类:

package proxy.staticy;public class ProxySubject implements Subject {    private Subject delegate;    public ProxySubject(Subject delegate) {        this.delegate = delegate;    }    @Override    public void dealTask(String taskName) {        long start = System.currentTimeMillis();        delegate.dealTask(taskName);        long end = System.currentTimeMillis();        System.out.println("任务耗时" + (end - start) + "毫秒");    }}

Code list 4,生成代理的工厂类:

package proxy.staticy;public class SubjectStaticFactory {    public static Subject getInstance() {        return new ProxySubject(new RealSubject());    }}

Code list 5,模拟客户端:

package proxy.staticy;public class Client1 {    public static void main(String[] args) {        Subject myProxy = SubjectStaticFactory.getInstance();        myProxy.dealTask("Task one");    } }

三、动态代理

代理类的源码在运行时有虚拟机反射生成,因此不存在字节码文件,代理类和委托类的关系在运行时确定。

Code list 6,动态代理对应的调用处理器:(说白了就是类似于代理的类)

/** * 动态代理对应的调用处理器 */package proxy.dynamic;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class SubjectInvocationHandler implements InvocationHandler {                                                                                                                                                                                                                                                                                                                                                   // 代理类持有一个委托类的对象引用    private Object delegate;                                                                                                                                                                                                                                                                                                                                                   public SubjectInvocationHandler(Object delegate){        this.delegate = delegate;    }                                                                                                                                                                                                                                                                                                                                                   @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        long start = System.currentTimeMillis();                                                                                                                                                                                                                                                                                                                                                           // Method的invoke返回Object对象方法执行的结果        method.invoke(delegate, args);                                                                                                                                                                                                                                                                                                                                                           long end = System.currentTimeMillis();                                                                                                                                                                                                                                                                                                                                                           System.out.println("任务执行耗时"+(end - start)+"毫秒");                                                                                                                                                                                                                                                                                                                                                           return null;    }}

Code list 7,生成动态代理对象的工厂类:

/** * 生成动态代理对象的工厂. */package proxy.dynamic;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import proxy.staticy.RealSubject;import proxy.staticy.Subject;/** * 客户端调用此方法获得代理对象, * 对客户端来说,并不知道获取的是代理对象还是委托对象。 */public class DynamicProxyFactory {    public static Subject getInstance() {        Subject delegate = new RealSubject();        InvocationHandler handler = new SubjectInvocationHandler(delegate);        Subject proxy = (Subject) Proxy.newProxyInstance(                delegate.getClass().getClassLoader(),                new Class[] {Subject.class},                handler);        return proxy;    }}

Code list 8,模拟客户端:

package proxy.dynamic;import proxy.staticy.Subject;public class Client2 {    public static void main(String[] args) {        Subject myProxy = DynamicProxyFactory.getInstance();        myProxy.dealTask("Task two");    }}