高新技术知识——动态代理

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

29,高新技术——动态代理

29.1 代理的作用

为目标类增加一些辅助功能.

示意图:

 

 

 29.2 创建动态代理类的对象

由于目标类是任意的,如何才能很方便的创建任意一个目标类的代理对象,可以调用java.lang.reflect.Proxy类中的静态方法:
public static Object newProxyInstance(ClassLoader loader,Class<?>[]interfaces,InvocationHandler h)throws IllegalArgumentException

 

此方法需要三个参数:

loader -代理类的类加载器

interfaces - 代理类要实现的接口列表(与目标类实现的接口相同,由于接口可以多实现,所以这里是一个数Class数组).

h - 指派方法调用的调用处理程序

 

如:创建一个目标类:ArrayList的代理.

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Date;

public class ProxyDemo {

   public static void main(String[]args) {

      //创建代理类的对象.

      Collection coll=(Collection)Proxy.newProxyInstance(

            Collection.class.getClassLoader(),

            new Class[]{Collection.class},

            new InvocationHandler(){//用匿名内部类的形式创建InvocationHandler的子类对象,并覆盖其内部方法.

            ArrayList al=new ArrayList();//创建目标类对象.

                @Override

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

                   //需要增加的辅助功能.

                   long begintime=System.currentTimeMillis();

                   //调用目标类的方法.

                   Object retVal=method.invoke(al, args);

                   //需要增加的辅助功能.

                   long costtime= System.currentTimeMillis()-begintime;

                   System.out.println(costtime);

                   return retVal;

                }});

      coll.add("abc");

      coll.add("abc");

      coll.add("abc");

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

  }
}

 

InvocationHandler中的invoke()方法,也接收了三个参数,为什么要接收这几个参数呢?

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

通过Proxy类的newInstance()方法,可以创建任意代理类的对象,当代理类执行一次目标类中的方法时,就会执行一次传入的InvocationHandler参数中的invoke()方法.

proxy接收代理类的对象,method接收的是代理类所执行的方法,args则表示代理类对象所调用的方法所传入的参数.

 

从上面的代码中可以看出,目标类的对象是在程序中自己new的,功能代码也需要自己写进去的,由于目标类和辅助功能代码的不确定性,可见代码的通用性较差.

如何能够动态的创建代理类对象?

可以将,目标类和辅助功能封装成对象以参数的形式传递给InvocationHandler

如:

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Date;

 

public class ProxyDemo {

   public static void main(String[] args) {

      ArrayList al=new ArrayList();//创建目标类的对象.

      Collection coll=(Collection)new GetProxyClass().getProxy(al,new MyAdvice());

      coll.add("abc");

      coll.add("abc");

      coll.add("abc");

      System.out.println(coll.size());
   }
}

class GetProxyClass{//定义获取代理类对象的类.

   private Objecttarget;

   private Adviceadvice;

   public Object getProxy(final Object target,final Advice advice){//将目标对象和辅助功能作为参数传递给方法getProxy.

      Object proxy=Proxy.newProxyInstance(

            target.getClass().getClassLoader(),//获取代理类的类加载器.

            target.getClass().getInterfaces(),//获取代理类的实现接口.

            new InvocationHandler(){//创建 InvocationHandler的子类对象,并覆盖方法.

                @Override

                public Object invoke(Object proxy, Method method,

                      Object[] args)throws Throwable {

                   advice.beforeMethod();//使用辅助功能.

                   Object retVal=method.invoke(target, args);

                   advice.afterMethod();//使用辅助功能.

                   return retVal;

                }});

      return proxy;
   }
}

interface Advice{//定义接口,提高程序的扩展性.

   void beforeMethod();

   void afterMethod();

}

class MyAdvice implements Advice{//辅助功能实现接口.

   private long begintime;

   private long endtime;

   //定义辅助功能

   @Override

   public void beforeMethod() {

      begintime=System.currentTimeMillis();

   }

   //定义辅助功能

   @Override

   publicvoid afterMethod() {
      endtime=System.currentTimeMillis();
      System.out.println(endtime-begintime);

   }

}


 

由此可见,通过动态代理可以对任意目标类完成辅助功能的添加.

 

 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值