黑马程序员技术交流社区

标题: 动态代理的问题 [打印本页]

作者: 无气打火机    时间: 2013-7-29 23:40
标题: 动态代理的问题
本帖最后由 杜光 于 2013-7-30 11:02 编辑
  1. package com.itheima.dynamic.proxy;
  2.                         public interface Subject {
  3.                                 public void request();
  4.                         }

  5.                         package com.itheima.dynamic.proxy;
  6.                         public class RealSubject implements Subject {
  7.                                 @Override
  8.                                 public void request()
  9.                                 {
  10.                                         System.out.println("需要被代理的任务。。。");
  11.                                 }
  12.                         }

  13.                         package com.itheima.dynamic.proxy;
  14.                         import java.lang.reflect.InvocationHandler;
  15.                         import java.lang.reflect.Method;
  16.                         public class DynamicSubject implements InvocationHandler {
  17.                                 private Subject sub;
  18.                                 public DynamicSubject(Subject sub)
  19.                                 {
  20.                                         this.sub = sub;
  21.                                 }
  22.                                 @Override
  23.                                 public Object invoke(Object proxy, Method method, Object[] args)
  24.                                                 throws Throwable
  25.                                 {
  26.                                         System.out.println("被代理执行之前:" + method);
  27.                                         method.invoke(sub, args);
  28.                                         System.out.println("被代理执行之后:" + method);
  29.                                         return null;
  30.                                 }
  31.                         }

  32.                         package com.itheima.dynamic.proxy;
  33.                         import java.lang.reflect.InvocationHandler;
  34.                         import java.lang.reflect.Proxy;
  35.                         public class Test {
  36.                                 public static void main(String[] args) {
  37.                                         //创建被代理类的对象
  38.                                         Subject sub = new RealSubject();
  39.                                         //创建代理类对象,并将被代理类传递进去
  40.                                         InvocationHandler handler = new DynamicSubject(sub);
  41.                                         //获取代理类的Class对象
  42.                                         Class c = handler.getClass();
  43.                                 
  44.                                         sub = (Subject)Proxy.newProxyInstance(c.getClassLoader(), sub.getClass().getInterfaces(), handler);//这里是什么意思?还有getInterfaces()这个方法时干什么的?
  45.                                         //调用方法
  46.                                         sub.request();
  47.                                         System.out.println("------------------------------------------------");
  48.                                         System.out.println("自动生成动态代理类的名字:" + sub.getClass().getName());
  49.                                         Class[] interfaces = sub.getClass().getInterfaces();
  50.                                         for(Class item : interfaces)
  51.                                                 System.out.println("自动生成动态代理类所实现的接口" + item);
  52.                                        
  53.                                 }
  54.                         }
复制代码

作者: 张云杰    时间: 2013-7-30 00:10
本帖最后由 张云杰 于 2013-7-30 00:36 编辑

sub = (Subject)Proxy.newProxyInstance(c.getClassLoader(), sub.getClass().getInterfaces(), handler);//这里是什么意思?还有getInterfaces()这个方法时干什么的?\

这句话的意思是说 创建了代理类的实例对象,  首先c.getClassLoader() 是目标类的类加载器, 然后sub.getClass().getInterfaces() 获取到目标类里所有实现的接口.. 如果传进去的是一个接口的话, 那么.. 就是jiekou.class

最后传进去一个要执行的方法.. 由代理执行.. 所以用到了InvocationHandler 接口..

InvocationHandler 里必须要有一个代理执行目标的方法, method.invoke(sub, args);  这个sub是从目标类的接口中获取.. 也就是说 代理延续了之前类执行的方法.. 交由代理去实现

这题由于老师跟API里说的有出入. 我跟同学讨论了一下.. 暂时不能给出正确的答案..

API里说的参数是代理类的类加载器, 老师视频里说的是目标类的类加载器

但是具体的思路还是一样的.. 就是不知道 到底是代理还是目标, 这个无法确定





作者: 冒烟的芒果    时间: 2013-7-30 00:44
本帖最后由 冒烟的芒果 于 2013-7-30 00:45 编辑

sub = (Subject)Proxy.newProxyInstance(c.getClassLoader(), sub.getClass().getInterfaces(), handler);
这句是调用Proxy类的静态方法创建一个代理实例;
首先你要知道 创建一个代理实例有两种方法,
一种是通过反射获得代理类Proxy的构造方法(因为Proxy的构造方法是被保护的,所以不能直接用构造方法创建一个实例),然后用这个创建一个实例(Proxy只有一个带参的构造函数);
另一种就是直接调用Proxy类的静态方法newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h),需要传入三个参数;也就是楼主用的这种。
至于getInterface()是返回sub对象所在的类实现的接口,并且返回的是class[]类型的,也正符合参数的要求。

作者: 王靖远    时间: 2013-7-30 11:00
getInterface是获得目标类接口。




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