动态代理类

本文通过实例详细解析了Java动态代理的工作原理。介绍了如何使用Proxy.newProxyInstance方法创建动态代理对象,并通过重写invoke方法来增强目标方法的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

谈谈自己对动态代理的理解,举个例子,

你现在有需求,需要把字串符"abc"放到一个集合里,

我们可以这样做:

       用new的方式创建一个集合

       List list = new ArrayList();

       然后调用add方法把字符串放进去

       list.add("abc");

 

那么,用动态代理怎么做呢,和上面很相似:

       List proxyList = ……;

       proxyList.add("abc");

省略号的内容暂且不表,可以看出,动态代理其实就是换种方式来完成目的罢了,

并且在达成目的的同时可以加上访问控制或者额外功能,上面的list.add完成的仅仅是要求的添加字符串功能,

而下面的proxyList.add,我们可以让它完成添加功能的同时具备别的能力,比如显示方法名,用的时间等等

那么省略号到底是什么呢?就是生成这个动态代理类的方法:

  List proxyList =  (List) Proxy.newProxyInstance(List.class.getClassLoader(), new Class[] { List.class },
    new InvocationHandler() {
           ArrayList target = new ArrayList();

          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                  long startTime = System.currentTimeMillis();
                  Object retVal = method.invoke(target, args);
                  long endTime = System.currentTimeMillis();
                 System.out.println(method.getName() + " running time is " + (endTime - startTime) + " millisecond.");
                 return retVal;
          }
    });
   proxyList.add("abc");

 执行结果:加入数据,并显示add running time is 0 millisecond.

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

这个方法看上去比较吓人,参数列表这么长,一一道来:(三个参数)

ClassLoader loader:一个类加载器,不用多说了

Class<?>[] interfaces:含有目的方法的接口数组,怎么理解呢?拿上面的例子说,你想要一个ArrayList,用它add方法添加字符串,

                                           而add方法是ArrayList实现的接口List中的方法,所以要让代理类拥有同样功能的话,要把List包含进去

InvocationHandler h: 这是代理实例的调用处理程序 实现的接口。该接口中只有 Object invoke(Object proxy, Method method, Object[] args) 方法,

                                         该方法 在代理实例上处理方法调用并返回结果。每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,

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

                                         简单的讲,上面的add方法就是在这个InvocationHandler实例里的invoke方法里实现的(Object retVal = method.invoke(target, args);)

                                         真正实现add方法的是封装在 InvocationHandler  实例中的ArrayList对象,这是一个双重invoke

 

这样就生成了一个实现List接口的动态代理类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值