Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 925|回复: 0

动态代理模式

  [复制链接]

该用户从未签到

发表于 2011-10-18 17:14:50 | 显示全部楼层 |阅读模式
一,为什么需要动态代理?

    在静态代理中一个代理类只能为一个接口服务,如果有很多个接口的话则就需要很多的代理类,而且所有的代理操作除了调用的方法不一样之外,其他的操作都一样,这就造成多个代理类的代码重复,为了解决静态代理的这个问题就有了动态代理。动态代理可以通过一个代理类完成全部的代理功能。

二,怎样实现动态代理?

    要实现动态代理就需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类的支持。

    可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject,InvocationHandler提供了一个

Object invoke(Object proxy,
              Method method,
              Object[] args)
              throws Throwable参数: proxy - 在其上调用方法的代理实例 method - 对应于在代理实例上调用的接口方法的 Method 实例。Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。 args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中。 返回: 从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为 null 并且接口方法的返回类型是基本类型,则代理实例上的方法调用将抛出 NullPointerException。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出 ClassCastException。 Proxy类是专门完成代理的操作类,可以通过此类为一个或者多个接口动态地生成实现类,此类实现了如下的操作方法:

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
                               throws IllegalArgumentException返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。此方法相当于:
     Proxy.getProxyClass(loader, interfaces).
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });
Proxy.newProxyInstance 抛出 IllegalArgumentException,原因与 Proxy.getProxyClass 相同。


参数:
loader - 定义代理类的类加载器
interfaces - 代理类要实现的接口列表
h - 指派方法调用的调用处理程序
返回:
一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口
ClassLoader是一个类加载器,如果要得到一个加载器的对象则需要使用Class类完成。



例子程序如下:

import java.lang.reflect.InvocationHandler ;
import java.lang.reflect.Proxy ;
import java.lang.reflect.Method ;
interface Subject{
public String say(String name,int age) ; // 定义抽象方法say
}
class RealSubject implements Subject{ // 实现接口
public String say(String name,int age){
  return "姓名:" + name + ",年龄:" + age ;
}
};
class MyInvocationHandler implements InvocationHandler{
private Object obj ;
public Object bind(Object obj){
  this.obj = obj ; // 真实主题类
  return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this) ;
}
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
  Object temp = method.invoke(this.obj,args) ; // 调用方法
  return temp ;
}
};
public class DynaProxyDemo{
public static void main(String args[]){
  Subject sub = (Subject)new MyInvocationHandler().bind(new RealSubject()) ;
  String info = sub.say("张三",30) ;
  System.out.println(info) ;
}
};
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-10 14:46 , Processed in 0.434585 second(s), 46 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表