说起代理,字面上的意思就是代替处理的意思,在java中代理就是一个对象代理另一个对象做着同样的事情,但是可以有更多的处理这件事情的其他功能,说起代理必不可少的就是反射机制,因为动态代理是在程序运行过程中才能够产生的类。动态代理运用的范围很多,比如spring的aop机制就是动态代理,其实动态代理也可以当做是拦截器,等等。
public interface Life { public void cook(); public void isGood(); }
public interface Work { public void code(); public int time(); }
public class Man implements Work,Life { @Override public void cook() { System.out.println("I am start cooking ....."); } @Override public void isGood() { System.out.println("my meal is good"); } @Override public void code() { System.out.println("I am start coding....."); } @Override public int time() { System.out.println("I have coded 8h"); return 8; } }
public class MyHandler implements InvocationHandler { private Object target;//此处的是需要被代理的对象,这样被代理的对象就可以和处理器关联起来 public MyHandler(Object target){ this.target=target; } @Override public java.lang.Object invoke(java.lang.Object proxy, Method method, java.lang.Object[] args) throws Throwable { /* * 个人此处也可以当做一个拦截器或者过滤器,因为在调用方法之前可以根据target的属性判断此对象是否可以做相应的事情 * */ /* * 三个参数: * proxy:生成的那个代理对象,在使用的过程中几乎没有使用过着过这个对象,所以可以用来看看代理的信息 * method:代理所调用的那个方法 * args:方法的参数 * */ System.out.println("动态代理调用函数开始.................."); Object obj=method.invoke(target,args);//方法中传入的是被代理的对象,这样在代理调用的时候其实就相当于被代理的对象在调用一样 System.out.println("动态代理调用函数结束.................."); return obj; } }
@Test public void test(){ //需要被代理的对象 Man man=new Man(); //处理器Handler,这里处理器要与被代理的对象与之相关联,这样才能在代理对象调用的时候犹如被代理对象调用一样 MyHandler myHandler=new MyHandler(man); /* * Proxy.newProxyInstance()中有三个参数 * classLoader:类加载器,任意一个类的classLoader都可以,一般使用被代理的类的即可 * interfaces:被代理对象的所有接口的数组,生成的代理对象会是这个数组里面的一个接口类型的代理对象 * handler:处理的Handler,这个类必须要得提供Handler,被代理对象的处理过程就是在handler中做的 * 返回值:返回值是Object,强行转为需要的接口类型 * */ Life life=(Life) Proxy.newProxyInstance(man.getClass().getClassLoader(),man.getClass().getInterfaces(),myHandler); life.cook(); life.isGood(); System.out.println(life.getClass()); System.out.println("------------------------------------------------------------------------"); Work work= (Work) Proxy.newProxyInstance(man.getClass().getClassLoader(),man.getClass().getInterfaces(),myHandler); work.code(); int time=work.time(); System.out.println(work.getClass()); }动态代理调用函数开始..................
class com.sun.proxy.$Proxy4
从上面的结果看,在每一个函数被调用之前之后都加上了一句话。生成的对象是一个Proxy类型的而不是任意一种接口类型的,但是确实接口的子类,原因如下:在程序运行的过程中当运行到newProxyInstance的时候JVM会根据所提供的classLoader,interfaces,handler去动态的生成字节码文件,我们是看不导这个.class文件的,而生成的类的父类是Proxy,实现了interfaces数组的接口,但是怎么由代理对象调用方法的时候转向handler的invoke方法,本人暂时是不知道。
可以参考如下文章,这个个人觉得写的比较好:https://www.ibm.com/developerworks/cn/java/j-lo-proxy1/index.html(可能需要)