前文讲解了代理的基本概念和静态代理机制: 设计模式之代理模式
java
如今来谈谈JAVA的动态代理机制设计模式
在java的动态代理机制中有一个重要的接口invocationhandler和一个重要的类Proxy,让咱们查看一下官方文档:数组
InvocationHandler is the interface implemented by the invocation handler of a proxy instance. Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.
代理实例的调用处理程序须要实现InvocationHandler接口.ide
每一个代理实例都关联了一个调用处理程序.当一个方法被代理实例调用时,这个方法的调用就会被加密并分发到调用程序的调用方法上.测试
翻译的很拗口,不要紧,代会看代码的执行流程就明白了.this
这个调用处理程序有一个调用方法:加密
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
处理代理对象的调用方法并返回结果 .当代理对象绑定的调用程序被调用时,这个方法就会被调用程序调用.spa
proxy 被调用方法的代理对象翻译
method 代理对象调用接口方法的相应方法.设计
args 经过代理对象接口调用方法传入的对象数组.接口方法没有参数则为空.
下面来看看proxy的文档描述:
public class Proxy extends Object implements Serializable
Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.
Proxy 提供静态方法建立动态代理了类和对象,同时也是这些方法建立代理对象的超类.
动态代理类是一个在运行时实现了一系列指定接口的方法的类.代理方法实现代理接口,代理类建立代理对象,每一个代理类都关联了一个实现了InvocationcationHandler接口的调用程序.代理对象的调用方法经过他的代理接口,被分发到实例调用程序的invoke方法上.经过反射机制,这个指定的方法就被调用了,而且传入一个对象数组.
Proxy的一些properties:
Proxy类是public,final,和非抽象的
代理类无需指定合法的名称,类名会以"$Proxy"开头
代理类须要继承Proxy
代理类须要按顺序实现建立时指定的各个接口
若是代理类实现的是非公共接口,那么它须要被定义在接口的同名包下.
因为代理类在建立时实现了指定的全部接口,因此在类对象上调用getInterfaces,将会返回一个接口列表的数组,调用getMetjods,将会返回实现全部接口方法的数组.调用getMethod将会返回proxy预期的方法.
Proxy.isProxyClass 判断是否是代理方法
代理类的java.security.ProtectionDomain,和系统类同样在被启动类加载
每个代理类都有一个带惨构造方法,实现InvocationHandler接口,并绑定调用程序到代理对象上.相比经过反射机制去获取构造方法,代理对象能够经过调用Proxy.newProxyInstance方法来构造代理对象.
代理接口的properties
代理类实现代理接口
每个代理实例都经过构造方法关联了一个调用程序.静态方法Proxy.getInvocationHandler将会返回一个由代理对象指定的调用程序
代理对象的接口方法调用将会被加密和分发到调用处理程序的invoke方法上.
hasCode,equals,toString等方法的调用都会被加密和分发到调用程序的invoke方法,接口方法也被一样的加密和分发.
话很少说,代码奉上:
首先定义一个接口:
package com.shadow.proxy.dynamicproxy; /** * * @author sunny */ public interface ITask { public void setData(String data); public int getCalData(int x); }
定义一个实现接口业务的真实主题:
package com.shadow.proxy.dynamicproxy; /** * * @author sunny */ public class TaskImpl implements ITask { @Override public void setData(String data) { System.out.println(data + "data is saved"); } @Override public int getCalData(int x) { return x * 10; } }
最关键的最核心的定义代理类:
package com.shadow.proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * * @author sunny */ public class DynamicProxy implements InvocationHandler { private Object obj; public DynamicProxy(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result; System.out.println("开始执行方法:" + method); result = method.invoke(obj, args); System.out.println(method + "方法执行结束"); return result; } }
编写测试文件:
package com.shadow.proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * * @author sunny */ public class TestProxy { public static void main(String[] args){ ITask realTask = new TaskImpl(); InvocationHandler handler = new DynamicProxy(realTask); ITask proxyTask = (ITask) Proxy.newProxyInstance(realTask.getClass().getClassLoader(), realTask.getClass().getInterfaces(), handler); proxyTask.setData("来一个汉堡"); System.out.println(proxyTask.getCalData(10)); } }