首先声明,本为并非原创,大量参考自,一方面做个备份,另一方面也是自己学习的过程。
一、代理
对一个类(委托类,实际完成工作的那个类)方法的调用交给另一个类(代理类,可以静态或动态生成)来完成。如果委托类和代理类实现了同一个接口,那么代理就可以很方便的完成。
二、静态代理
程序运行前代理类和委托类的关系就已经确定,代理类的字节码文件已经存在,代理不是运行时生成。
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"); }}