A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 无气打火机 中级黑马   /  2013-7-29 23:40  /  929 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杜光 于 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.                         }
复制代码

评分

参与人数 1技术分 +1 收起 理由
杜光 + 1 每天提问并回答问题,是对知识的复习和积累.

查看全部评分

3 个回复

倒序浏览
本帖最后由 张云杰 于 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里说的参数是代理类的类加载器, 老师视频里说的是目标类的类加载器

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




评分

参与人数 1技术分 +1 收起 理由
杜光 + 1 每天提问并回答问题,是对知识的复习和积累.

查看全部评分

回复 使用道具 举报
本帖最后由 冒烟的芒果 于 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[]类型的,也正符合参数的要求。

评分

参与人数 1技术分 +1 收起 理由
杜光 + 1

查看全部评分

回复 使用道具 举报
getInterface是获得目标类接口。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马