`
yahaitt
  • 浏览: 759970 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

Java反射机制之代理模式

阅读更多

代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

代理模式一般涉及到的角色有
抽象角色:声明真实对象和代理对象的共同接口
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象

动态代理中最关键的两点是:

InvocationHandler 接口的实现

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)的方法的调用

一、原理示例

java 代码
  1. /*  
  2.  * 创建日期 2007-3-13  
  3.  *  
  4.  * TODO 要更改此生成的文件的模板,请转至  
  5.  * 窗口 - 首选项 - Java - 代码样式 - 代码模板  
  6.  */  
  7. package com.langsin.proxy;   
  8.   
  9. // 抽象角色   
  10.   
  11. abstract public class Subject   
  12.   
  13. {   
  14.   
  15.     abstract public void request();   
  16.   
  17. }   

 

java 代码
  1. package com.langsin.proxy;   
  2.   
  3. //真实角色:实现了Subject的request()方法   
  4.   
  5. public class RealSubject extends Subject   
  6. {   
  7.   
  8.     public RealSubject()   
  9.     {   
  10.     }   
  11.   
  12.     public void request()   
  13.     {   
  14.         System.out.println("From real subject.");   
  15.     }   
  16.   
  17. }   

 

java 代码
  1. package com.langsin.proxy;   
  2.   
  3. //代理角色   
  4.   
  5. public class ProxySubject extends Subject   
  6.   
  7. {   
  8.     private RealSubject realSubject; // 以真实角色作为代理角色的属性   
  9.   
  10.     public ProxySubject()   
  11.     {   
  12.     }   
  13.   
  14.     public void request() // 该方法封装了真实对象的request方法   
  15.   
  16.     {   
  17.         preRequest();   
  18.   
  19.         if (realSubject == null)   
  20.         {   
  21.             realSubject = new RealSubject();   
  22.         }   
  23.   
  24.         realSubject.request(); // 此处执行真实对象的request方法   
  25.   
  26.         postRequest();   
  27.     }   
  28.   
  29.     private void preRequest()   
  30.     {   
  31.   
  32.         // something you want to do before requesting   
  33.   
  34.     }   
  35.   
  36.     private void postRequest()   
  37.     {   
  38.   
  39.         // something you want to do after requesting   
  40.   
  41.     }   
  42.   
  43. }   

 

java 代码
  1. package com.langsin.proxy;   
  2.   
  3. //客户端调用   
  4.   
  5. public class Client   
  6. {   
  7.     public static void main(String[] args)   
  8.     {   
  9.         Subject sub = new ProxySubject();   
  10.   
  11.         sub.request();   
  12.     }   
  13. }   

 

二、应用示例一、

java 代码
  1. package com.langsin.dynamicproxy;   
  2.   
  3. //抽象角色(之前是抽象类,此处应改为接口):    
  4.   
  5. public interface Subject   
  6. {   
  7.     abstract public void request();   
  8. }   

 

java 代码
  1. package com.langsin.dynamicproxy;   
  2.   
  3. //具体角色   
  4.   
  5. public class RealSubject implements Subject   
  6. {   
  7.   
  8.     public RealSubject()   
  9.     {   
  10.     }   
  11.   
  12.     public void request()   
  13.     {   
  14.         System.out.println("From real subject.");   
  15.     }   
  16.   
  17. }   

 

java 代码
  1. package com.langsin.dynamicproxy;   
  2.   
  3. import java.lang.reflect.InvocationHandler;   
  4. import java.lang.reflect.Method;   
  5. import java.lang.reflect.Proxy;   
  6. import java.util.List;   
  7. import java.util.Vector;   
  8.   
  9. public class VectorProxy implements InvocationHandler   
  10. {   
  11.     private Object proxyobj;   
  12.   
  13.     public VectorProxy(Object obj)   
  14.     {   
  15.         proxyobj = obj;   
  16.     }   
  17.   
  18.     public static Object factory(Object obj)   
  19.     {   
  20.         Class cls = obj.getClass();   
  21.   
  22.         return Proxy.newProxyInstance(cls.getClassLoader(),   
  23.                 cls.getInterfaces(), new VectorProxy(obj));   
  24.     }   
  25.   
  26.     public Object invoke(Object proxy, Method method, Object[] args)   
  27.             throws Throwable   
  28.     {   
  29.         System.out.println("before calling " + method);   
  30.   
  31.         if (args != null)   
  32.         {   
  33.             for (int i = 0; i < args.length; i++)   
  34.             {   
  35.                 System.out.println(args[i] + "");   
  36.             }   
  37.         }   
  38.         Object object = method.invoke(proxyobj, args);   
  39.   
  40.         System.out.println("after calling " + method);   
  41.         return object;   
  42.     }   
  43.   
  44.     @SuppressWarnings("unchecked")   
  45.     public static void main(String[] args)   
  46.     {   
  47.         List<string></string> v = (List<string></string>) factory(new Vector<string></string>(10));   
  48.   
  49.         v.add("New");   
  50.         v.add("York");   
  51.         System.out.println(v);   
  52.   
  53.         v.remove(0);   
  54.         System.out.println(v);   
  55.     }   
  56. }   

 

应用代码二、

java 代码
  1. package com.langsin.dynamicproxy;   
  2.   
  3. public interface Foo   
  4. {   
  5.     void doAction();   
  6. }   

 

java 代码
  1. package com.langsin.dynamicproxy;   
  2.   
  3. public class FooImpl implements Foo   
  4. {   
  5.     public FooImpl()   
  6.     {   
  7.     }   
  8.   
  9.     public void doAction()   
  10.     {   
  11.         System.out.println("in FooImp1.doAction()");   
  12.     }   
  13. }   

 

java 代码
  1. package com.langsin.dynamicproxy;   
  2.   
  3. public class FooImpl2 implements Foo   
  4. {   
  5.     public FooImpl2()   
  6.     {   
  7.     }   
  8.   
  9.     public void doAction()   
  10.     {   
  11.         System.out.println("in FooImp2.doAction()");   
  12.     }   
  13.   
  14. }   
java 代码
  1. package com.langsin.dynamicproxy;   
  2.   
  3. import java.lang.reflect.InvocationHandler;   
  4. import java.lang.reflect.Method;   
  5.   
  6. public class CommonInvocationHandler implements InvocationHandler   
  7. {   
  8.   
  9.     // 动态执行对象,需要回调的对象   
  10.     private Object target;   
  11.   
  12.     // 支持构造子注射   
  13.     public CommonInvocationHandler()   
  14.     {   
  15.   
  16.     }   
  17.   
  18.     // 支持构造子注射   
  19.     public CommonInvocationHandler(Object target)   
  20.     {   
  21.         setTarget(target);   
  22.     }   
  23.   
  24.     /**  
  25.      *   
  26.      * 采用setter方法注射  
  27.      *   
  28.      * @param target  
  29.      *   
  30.      */  
  31.     public void setTarget(Object target)   
  32.     {   
  33.         this.target = target;   
  34.     }   
  35.   
  36.     /**  
  37.      *   
  38.      * 调用proxy中指定的方法method,并传入参数列表args  
  39.      *   
  40.      * @param proxy  
  41.      *            代理类的类型,例如定义对应method的代理接口  
  42.      *   
  43.      * @param method  
  44.      *            被代理的方法  
  45.      *   
  46.      * @param args  
  47.      *            调用被代理方法的参数  
  48.      *   
  49.      * @return  
  50.      *   
  51.      * @throws java.lang.Throwable  
  52.      *   
  53.      */  
  54.   
  55.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable   
  56.     {   
  57.         return method.invoke(target, args);   
  58.     }   
  59.   
  60. }   

 

java 代码
  1. package com.langsin.dynamicproxy;   
  2.   
  3. import java.lang.reflect.Proxy;   
  4.   
  5. public class Demo   
  6. {   
  7.     public static void main(String[] args)   
  8.     {   
  9.   
  10.         // 1.通用的动态代理实现   
  11.   
  12.         CommonInvocationHandler handler = new CommonInvocationHandler();   
  13.   
  14.         Foo f;   
  15.   
  16.         // 2.接口实现1   
  17.   
  18.         handler.setTarget(new FooImpl());   
  19.   
  20.         // 方法参数说明:代理类、代理类实现的接口列表、代理类的处理器   
  21.   
  22.         // 关联代理类、代理类中接口方法、处理器,当代理类中接口方法被调用时,会自动分发到处理器的invoke方法   
  23.   
  24.         // 如果代理类没有实现指定接口列表,会抛出非法参数异常   
  25.   
  26.         f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),   
  27.   
  28.         new Class[] { Foo.class },   
  29.   
  30.         handler);   
  31.   
  32.         f.doAction();   
  33.   
  34.         // 3.接口实现2   
  35.   
  36.         handler.setTarget(new FooImpl2());   
  37.   
  38.         f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),   
  39.   
  40.         new Class[] { Foo.class },   
  41.   
  42.         handler);   
  43.   
  44.         f.doAction();   
  45.     }   
  46. }   
分享到:
评论

相关推荐

    yolo算法-电线杆数据集-1493张图像带标签-.zip

    yolo算法-电线杆数据集-1493张图像带标签-.zip;yolo算法-电线杆数据集-1493张图像带标签-.zip;yolo算法-电线杆数据集-1493张图像带标签-.zip

    yolo算法-电线杆数据集-7255张图像带标签-杆顶.zip

    yolo算法-电线杆数据集-7255张图像带标签-杆顶.zip;yolo算法-电线杆数据集-7255张图像带标签-杆顶.zip;yolo算法-电线杆数据集-7255张图像带标签-杆顶.zip;yolo算法-电线杆数据集-7255张图像带标签-杆顶.zip

    pillow_avif_plugin-1.2.1-cp37-cp37m-win32.whl.rar

    python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。

    【地震】基于matlab时域有限差分FDTD模拟地震盾构【含Matlab源码 9186期】.mp4

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    中国高质量发展指标体系-最新发布.zip

    中国高质量发展指标体系-最新发布.zip

    【java毕业设计】班级同学录管理系统源码(ssm+mysql+说明文档).zip

    环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上 服务器:tomcat7及以上

    【java毕业设计】基于Java的汽车销售系统源码(ssm+mysql+说明文档).zip

    环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上 服务器:tomcat7及以上

    yolo算法-动物检测数据集-3948张图像带标签.zip

    yolo系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值

    pandas-1.3.5-pp38-pypy38_pp73-win_amd64.whl.rar

    PartSegCore_compiled_backend-0.12.0a0-cp36-cp36m-win_amd64.whl.rar

    planar-0.4-cp39-cp39-win_amd64.whl.rar

    python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。

    中国企业统计年鉴全集(1990-2020,除1997年).zip

    中国企业统计年鉴全集(1990-2020,除1997年).zip

    oursql-0.9.4-cp34-none-win32.whl.rar

    PartSegCore_compiled_backend-0.12.0a0-cp36-cp36m-win_amd64.whl.rar

    yolo算法-交易是项目数据集-760张图像带标签-.zip

    yolo系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值

    【java毕业设计】中国古诗词学习平台源码(ssm+mysql+说明文档).zip

    环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上 服务器:tomcat7及以上

    汽车功放电路设计PCB案例

    内含PCB设计案例,可直接打样出成果

    Pillow_SIMD-6.0.0.post0-cp27-cp27m-win32.whl.rar

    python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。

    polylearn-0.1.dev0-cp27-cp27m-win32.whl.rar

    python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。

    中国各省市进出口面板数据集.zip

    中国各省市进出口面板数据集.zip

    【java毕业设计】大学生社团管理系统源码(ssm+mysql+说明文档).zip

    环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上 服务器:tomcat7及以上

    appium test for self

    appium test for self 1. env create 2.coding

Global site tag (gtag.js) - Google Analytics