黑马程序员—动态代理

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

动态代理类是一个实现在创建类时在运行时指定的接口列表的类,

 该类具有下面描述的行为。 代理接口 是代理类实现的一个接口。

 代理实例 是代理类的一个实例。

 每个代理实例都有一个关联的调用处理程序 对象,

 它可以实现接口 InvocationHandler

 通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,

 并传递代理实例、识别调用方法的 java.lang.reflect.Method 对象以及包含参数的 Object 类型的数组。

 调用处理程序以适当的方式处理编码的方法调用,

 并且它返回的结果将作为代理实例上方法调用的结果返回

 

Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类

 

publicclass ProxyDemo1

{

    publicstaticvoid main(String[] args)

    {

       //创建一个collection类的动态代理类

       Class clazzproxy = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);

 

       //输出这个动态代理类的名字

       System.out.println(clazzproxy.getName().toString());

      

       //获得这个动态代理类的所有构造方法

       getInstances(clazzproxy);

      

       //分界,上面是构造方法下面是方法

       System.out.println("=============================================================");

      

       //获得这个动态代理类的所有方法

       getMethods(clazzproxy);

      

    }

下面是getInstance方法,获得动态代理类的所有构造方法

publicstaticvoid getInstances(Class clazzproxy)

    {

       //获得构造方法的数组

       Constructor[] constructors = clazzproxy.getConstructors();

      

       //遍历构造方法数组,并输出每个构造方法的参数类型

       for(Constructor c : constructors)

       {

           String name = c.getName();

          

           StringBuilder sb = new StringBuilder();

          

           sb.append(name+"(");

          

           //获得构造方法的参数类型的Class数组

           Class[] clazzparams = c.getParameterTypes();

          

           //遍历参数类型数组,并把参数一个一个的加入sb

           for(Class param : clazzparams)

           {

              sb.append(param.getName().toString()+",");

           }

          

           //如果参数数组为空,就把()中加入一个逗号,便于统一删除最后一个逗号

           if(clazzparams.length==0)

              sb.append(",");

          

           //删除最后一个参数后面的多余的逗号

           sb.deleteCharAt(sb.length()-1);

          

           sb.append(")");

          

           System.out.println(sb.toString());

       }

    }

getMethod获得动态代理类的所有方法

根据获得动态代理类的构造方法的原理获得动态代理类的所有方法

    publicstaticvoid getMethods(Class clazzproxy)

    {

       Method[] methods = clazzproxy.getMethods();

      

       for(Method m : methods)

       {

           String name = m.getName();

          

           StringBuilder sb = new StringBuilder();

          

           sb.append(name+"(");

          

           Class[] clazzparams = m.getParameterTypes();

          

           for(Class param : clazzparams)

           {

              sb.append(param.getName().toString()+",");

           }

          

           if(clazzparams.length==0)

              sb.append(",");

          

           sb.deleteCharAt(sb.length()-1);

          

           sb.append(")");

          

           System.out.println(sb.toString());

          

       }

    }

 

InvocationHandler 类:

   代理实例的调用处理程序 实现的接口。

   每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,

   将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法

  

总结创建动态类的实例对象的步骤:         

1、创建一个collection类的动态代理类

       例:Class clazzproxy = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);

2、利用反射获得动态代理类的构造方法,构造方法中参数类型为InvocationHandler

       Constructor constructor = clazzproxy.getConstructor(InvocationHandler.class);

3、利用反射创建实现动态代理的Collection

       Collection coll = (Collection) constructor.newInstance(new MyInvocationHandler());

 

 

简单方法创建动态类的实例对象

     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class },handler);

 

 

publicclass ProxyDemo2

{

    publicstaticvoid main(String[] args) throws Exception

    {

       //创建一个collection类的动态代理类

       Class clazzproxy = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);

 

       //输出这个动态代理类的名字

       System.out.println(clazzproxy.getName().toString());

      

       //获得动态代理类的构造方法,利用反射

       Constructor constructor = clazzproxy.getConstructor(InvocationHandler.class);

 

       class MyInvocationHandler implements InvocationHandler

       {

 

           @Override

           public Object invoke(Object proxy, Method method, Object[] args)throws Throwable

           {

             

              returnnull;

           }

          

       }

      

       //利用反射创建实现动态代理的Collection类,使用自己的MyInvocationHandler方法

       Collection proxy1 = (Collection) constructor.newInstance(new MyInvocationHandler());

      

       System.out.println(proxy1);

       //利用反射创建实现动态代理的Collection类,使用自带的InvocationHandler方法

       Collection proxy2 = (Collection) constructor.newInstance(new InvocationHandler() {

          

           @Override

           public Object invoke(Object proxy, Method method, Object[] args)

                  throws Throwable {

              // TODO Auto-generated method stub

              returnnull;

           }

       });

       //利用反射创建实现动态代理的Collection类,直接用Proxy的构造方法

       Collection proxy3 = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),

              new Class[]{ Collection.class},

              new InvocationHandler()

              {

          

                  ArrayList arr = new ArrayList();

                 

                  @Override

                  public Object invoke(Object proxy, Method method, Object[] args)throws Throwable

                  {

                    

                     long begintime = System.currentTimeMillis();

                     Object value = method.invoke(arr, args);

                     long endtime = System.currentTimeMillis();

                     System.out.println(method.getName()+"运行时间:"+(endtime-begintime));

                     return value;

                  }

              }

       );

      

       proxy3.add("111");

      

       proxy3.add("222");

      

       proxy3.add("333");

      

       System.out.println(proxy3.size());

      

    }

 

}

 

 

 

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值