黑马程序员技术交流社区

标题: 关于复写InvocationHandler中invoke方法参数的问题 [打印本页]

作者: yufeng47    时间: 2013-4-19 09:33
标题: 关于复写InvocationHandler中invoke方法参数的问题
  1. /**
  2. *在方法getProxy当中,通过newProxyInstance()方法可以创建一个代理类的实例对象,
  3. *在该方法内部通过其三个参数在底层创建一个代理类对象(Object)proxy:
  4. *1、Class<?> clazzs =
  5. *                getProxyClass(target.getClass().getClassLoader(),target.getClass().getInterfaces());
  6. *2、final Constructor<?> cons = clazzs.getConstructor(constructorParams);
  7. *3、Object proxy = cons.newInstance(new InvocationHandler());
  8. *
  9. *问题:
  10. *如proxy.add("flx");实例方法调用过程中产生的三个参数:(Collection)proxy,(Method)add,(Parameter)"flx";
  11. *对于第3步,InvocationHandler接口中的方法invoke,接收的三个参数分别与上面三个参数相对应,但是invoke是一个
  12. *抽象方法,在程序中是根本看不到一点联系关系的,在JAVA中他们是怎么做到相对应的?又是怎么调用这三个参数的?
  13. *
  14. */

  15. package cn.itcast.day3;

  16. import java.lang.reflect.InvocationHandler;
  17. import java.lang.reflect.Method;
  18. import java.lang.reflect.Proxy;
  19. import java.util.ArrayList;
  20. import java.util.Collection;

  21. import cn.itcast.day3.aopframework.Advice;
  22. import cn.itcast.day3.aopframework.MyAdvice;

  23. public class ProxyQuestion {

  24.         public static void main(String[] args) throws Exception {
  25.                 final ArrayList<Object> target = new ArrayList<Object>();
  26.                 @SuppressWarnings("unchecked")
  27.                 Collection<Object> proxy = (Collection<Object>) getProxy(target, new MyAdvice());
  28.                 proxy.add("flx");
  29.                 proxy.add("bxd");
  30.                 System.out.println(proxy.size());
  31.                 System.out.println(proxy.toString());
  32.                 System.out.println(proxy.getClass().getName());
  33.         }
  34.        
  35.         private static Object getProxy(final Object target, final Advice advice)throws Exception{
  36.                
  37.                 Object retProxy = Proxy.newProxyInstance(
  38.                                 target.getClass().getClassLoader(),
  39.                                 target.getClass().getInterfaces(),
  40.                                 new InvocationHandler() {
  41. //                                        invoke中的参数proxy代理类是通过target的类加载器、其继承接口以及调用处理程序获得的。
  42.                                         @Override
  43.                                         public Object invoke(Object proxy, Method method, Object[] args)
  44.                                                         throws Throwable {
  45.                                                 advice.beforeTime();
  46.                                                 Object retVal =  method.invoke(target, args);
  47.                                                 advice.afterTime(method);
  48.                                                 return retVal;
  49.                                         }
  50.                                 });
  51.                 return retProxy;
  52.         }
  53. }
复制代码

作者: 杜鹏飞    时间: 2013-4-19 11:47
前几天我也因为这个问题傻了.
其实很简单,我们要代理甚么类,Proxy就必须要通过某种方法用到那个类.
我们要调用Proxy所模拟接口的任一方法,Proxy就调用自己的invoke方法,并将参数传进去.
我们可以像静态代理那样,将要代理的类作为Proxy的成员变量.
也可以通过你的这种写法,在new InvocationHandler(){...}中通过闭包来使用超值.






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2