黑马程序员技术交流社区

标题: 张老师的代理,听得有点晕!求高手讲讲。 [打印本页]

作者: 花伟昌    时间: 2013-8-5 21:10
标题: 张老师的代理,听得有点晕!求高手讲讲。
本帖最后由 杨兴庭 于 2013-8-6 21:19 编辑

请教各位同学,关于代理的知识。
作者: 哪颗最亮的星星    时间: 2013-8-5 22:03
代理其实就是一个中介,本来你想买电脑要去北京的联想总部,但现在你只需要通过你们县城的代理商就可以买到了,一句话,方便。这里我写一个死的代理,也就是一个没有扩展的代理,哪么代码的代理实现如下:
Collection c=(Collection)Proxy.newProxyInstance(
                                Collection.class.getClassLoader(),
                                new Class []{Collection.class},
                                new InvocationHandler()
                                {
                                        ArrayList<String> al=new ArrayList<String>();//目标
                                        @Override
                                        public Object invoke(Object proxy, Method method, Object [] args)throws Throwable
                                        {
                                                long start=System.currentTimeMillis();//系统功能
                                               
                                                Object retVal=method.invoke(al,args);//代理去调用目标的方法
                                               
                                                long end=System.currentTimeMillis();//系统功能
                                               
                                                System.out.println(end-start);
                                               
                                                return retVal;
                                        }
                                });
               
               
                c.add("abcd");
                c.add("absd");
                c.add("abdd");
                c.add("abfd");
                System.out.println(c);
作者: 白堇翎    时间: 2013-8-5 22:29
本帖最后由 白堇翎 于 2013-8-5 22:31 编辑

楼上已经把概念讲的很清楚了,我就来个封装好的代理类吧,可能具体的代码能帮助你更好的理解什么是"动态代理类"
  1. package ProxyClass;

  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. import java.util.ArrayList;
  6. import java.util.Collection;

  7. /*
  8. * 代理类练习
  9. * */
  10. public class ProxyTest {

  11.         public static void main(String[] args) {
  12.                 // TODO Auto-generated method stub
  13.                 pro pro = new clspro();
  14.                 Test3Proxy T3P = new Test3Proxy();
  15.                 ArrayList al = new ArrayList();
  16.                 Collection coll = (Collection)T3P.proxy(al, pro);
  17.                 //随便添加点东西试试我的代理类
  18. coll.add(123);
  19.                 coll.add(123);
  20.                 coll.add(123);
  21.                 coll.add(123);
  22.                 coll.add(123);
  23.                
  24.         }
  25. }
  26. //一个封装好的代理类,直接往里传你自己想要的代理的类,增加的功能即可,前提是你的类必须实现pro接口
  27. class Test3Proxy{
  28.         public Object proxy(final Object targent,final pro pro){
  29.                 Object tar = Proxy.newProxyInstance(
  30.                                 targent.getClass().getClassLoader(),
  31.                                 targent.getClass().getInterfaces(),
  32.                                 new InvocationHandler() {
  33.                                        
  34.                                         @Override
  35.                                         public Object invoke(Object proxy, Method method, Object[] args)
  36.                                                         throws Throwable {
  37.                                                 // TODO Auto-generated method stub
  38.                                                 pro.before();
  39.                                                 Object obj = method.invoke(targent, args);
  40.                                                 pro.after();
  41.                                                 return obj;
  42.                                         }
  43.                                 });
  44.                 return tar;
  45.         }
  46. }
  47. //接口,用于声明要添加的功能
  48. interface pro{
  49.         void before();
  50.         void after();
  51. }
  52. //随便写一个实现pro接口的类,随便添加点功能
  53. class clspro implements pro{
  54.         long start;
  55.         long end;
  56.         @Override
  57.         public void before() {
  58.                 // TODO Auto-generated method stub
  59.                 start = System.currentTimeMillis();
  60.         }

  61.         @Override
  62.         public void after() {
  63.                 // TODO Auto-generated method stub
  64.                 end =System.currentTimeMillis();
  65.                 System.out.println(end-start);
  66.         }
  67.         
  68. }
复制代码

作者: 佟都    时间: 2013-8-5 23:20
本帖最后由 佟都 于 2013-8-6 00:09 编辑

刚开始的时候,我也听晕了。

现在我是这么理解的:
所谓“动态代理类”的“动态”,是指代理类是动态生成的

  1. //创建动态代理类(通过Proxy的静态方法getProxyClass)
  2. public static void main(String[] args) {
  3.   //获取Collection接口的代理类
  4.   Class proxyClass = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
  5.   System.out.println("class name : "+ proxyClass.getName());
  6.   //对同一接口重复创建动态代理类,会返回先前已经创建好的代理类的类对象
  7.   proxyClass = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
  8.   System.out.println("class name : "+ proxyClass.getName());
  9.   //获取Map接口的代理类
  10.   Class proxyClass1 = Proxy.getProxyClass(Map.class.getClassLoader(), Map.class);
  11.   System.out.println("class name : "+ proxyClass1.getName());
  12.   
  13.   //获取Comparator接口的代理类
  14.   Class proxyClass2 = Proxy.getProxyClass(Comparator.class.getClassLoader(), Comparator.class);
  15.   System.out.println("class name : "+ proxyClass2.getName());
  16. }
复制代码
接下来是“动态代理类”中的“代理类”。上一步动态生成的代理类是要用来实现、调用被代理的接口(委托类)中的方法的。
这是通过实现InvocationHandler接口中的invoke(),来分派转发委托类的方法,并可在此增加原委托类中没有的方法。

  1.         //创建动态代理类对象并调用委托类中的方法
  2.         public static void main(String[] args) throws Exception {
  3.                 //获取Collection接口的动态代理类
  4.                 Class proxyClass = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
  5.                 System.out.println("class name : "+ proxyClass.getName());
  6.                
  7.                 //通过反射机制获取动态代理类的构造方法
  8.                 Constructor constructor = proxyClass.getConstructors()[0];
  9.                
  10.                 //通过构造方法创建动态代理类的实例
  11.                 Collection proxy = (Collection)constructor.newInstance(
  12.                         //InvocationHandler接口作为参数被传入
  13.                         new InvocationHandler() {
  14.                                 //因为这里是委托类是Collection接口,可用ArrayList()对象来代替
  15.                                 ArrayList al = new ArrayList();
  16.                                 Object obj = null;
  17.                                 
  18.                                 @Override
  19.                                 public Object invoke(Object proxy, Method method, Object[] args) {
  20.                                         System.out.println("委托类方法运行前……");
  21.                                        
  22.                                         //委托类的方法运行
  23.                                         try {
  24.                                                 System.out.println("正在运行"+ method.getName() +"()...");
  25.                                                 obj = (Object) method.invoke(al, args);
  26.                                         } catch (Exception e) {
  27.                                                 e.printStackTrace();
  28.                                         }
  29.                                        
  30.                                         System.out.println("委托类方法运行后。");
  31.                                         return obj;
  32.                                 }
  33.                         });
  34.                
  35.                 //通过动态代理类对象来调用委托类的方法
  36.                 System.out.println("proxy.toString() = "+ proxy.toString());
  37.                 proxy.add("haha");
  38.                 proxy.add("hehe");
  39.                 System.out.println("proxy.size() = "+ proxy.size());
  40.                 System.out.println("proxy.toString() = "+ proxy.toString());
  41.         }
复制代码





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