import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class DynamicProxy implements InvocationHandler { private Object object; public Object bind(Object object) { this.object = object; return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before say!!"); Object result=method.invoke(object,args); System.out.println("before say!!"); return result; }}
接口IspeakInterface
public interface IspeakInterface { public void say(); public void sing();}
实现类A:
public class SpeakEnglish implements IspeakInterface { @Override public void say() { System.out.println("Hello"); } @Override public void sing() { System.out.println("Merry Christmas!!"); }}
实现类B:
public class SpeakChinese implements IspeakInterface { @Override public void say() { System.out.println("你好!!"); } @Override public void sing() { System.out.println("北京欢迎您!!"); }}
测试类:
public class TestProxy { public static void main(String[] args) { DynamicProxy dynamicProxy=new DynamicProxy(); IspeakInterface ispeak=(IspeakInterface)dynamicProxy.bind(new SpeakChinese()); ispeak.say(); ispeak.sing(); }}
这里面最重要的就是代理类,也就是上述的DynamicProxy类,在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。
每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用 一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。我们来看看InvocationHandler这个接口的唯一一个方法 invoke 方法:
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
Object invoke(Object proxy, Method method, Object[] args) throws Throwableproxy: 指代我们所代理的那个真实对象method: 指代的是我们所要调用真实对象的某个方法的Method对象args: 指代的是调用真实对象某个方法时接受的参数
Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法:
public static Object newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler h) throws IllegalArgumentException
这个方法的作用就是得到一个动态的代理对象,其接收三个参数,我们来看看这三个参数所代表的含义:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
loader: 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
h: 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上