博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
代理模式
阅读量:5102 次
发布时间:2019-06-13

本文共 3013 字,大约阅读时间需要 10 分钟。

定义:为其他对象提供一种代理以控制对这个对象的访问。代理模式本质上也叫做委托模式,它是一种基本设计技巧,许多其他模式,比如状态模式,策略模式,访问者模式本质上是在特殊场合采用了委托模式。代理模式应用非常广泛,下面举出一个通用示例,假设现有三个角色,抽象主题、具体实现主题、代理主题:

//抽象主题类public interface Subject{    public void request();}//真实主题类public class RealSubject implements Subject{    //实现方法    public void request(){    }}//代理类public class Proxy implements Subject{    //要代理实现哪个类    private Subject subject = null;    //默认代理者    public Proxy(){        this.subject = new Proxy();    }    //通过构造函数传递代理类        public Proxy(Object... objects){            }    //实现接口中定义的方法    public void request(){        this.before();        this.subject.request();        this.after();    }    //预处理    private void before(){    }    //后处理    private void after(){    }}

代理模式有如下优点:

  • 职责清晰。真实的角色就是实现实际的业务逻辑,不用关心其他非本职的事务。
  • 高扩展性。具体主题角色是随时都会发生变化的,但只要他实现了接口,不管如何变化,都不会影响到代理类的使用
  • 智能化。比如动态代理

代理模式扩展:

  上述通用代码是普通代理,还可以改造为强制代理模式,也就是不允许直接new具体对象,必须通过代理产生;还有一种是个性化代理,一个类可以实现多个接口,完成不同任务的整合,代理的目的是在目标对象方法的基础上进行增强,这种增强本质上通常是拦截和过滤目标方法,只需要在普通代理类上实现更多接口即可实现;最后但很重要的一种就是动态代理,什么是动态代理?就是在实现阶段不用关心代理谁,只在运行阶段才指定代理哪个对象。相对而言,自己写代理类就是静态代理。现在非常常见的面向横切面编程,也就是AOP,其核心就是动态代理机制。

  提到动态代理,必须说下jdk提供的一个动态代理接口:InvocationHandler,通过这个接口,所有的方法都由该handler来处理,由它接管所有实际的处理任务。下面看一个动态代理通用编程模型,

  先看Subject接口,抽象主题类:

public interface Subject{    //业务操作    public void doSomething(String str);}

  实现主题类:

//真实主题类public class RealSubject implements Subject{    //业务操作    public void doSomething(String str){    }}

  重点的动态代理类:

//动态代理的Handler类 public class MyInvocationHandler implements InvocationHandler{    //被代理的对象    private Object target = null;    //传递一个对象    public MyInvocationHandler(Object _obj){        this.target = _obj;    }    //代理方法    public Object invoke(Object proxy, Method method, Object[] args) throws Throwble{      return method.invoke(this.target, args);    }}

  所有通过动态代理实现的全部通过invoke()方法调用。动态代理:

public class DynamicProxy
{ public static
T newProxyInstance(ClassLoader loader,Class
interfaces, InvocationHandler h){ //寻找JoinPoint连接点,AOP框架使用元数据定义 if(true){ //执行一个前置通知 (new BeforeAdvice()).exec(); } return (T)Proxy.newProxyInstance(loader, interfaces, h);}public interface IAdvice{ public void exec();}public class BeforeAdvice implements IAdvice{ public void exec(){ }}//场景调用public class Client{ public static void main(String[] args){ Subject subject = new RealSubject(); //定义一个handler InvocationHandler hander = new MyInvocationHandle(subject); //定义主题的代理 Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass(),handler); proxy.doSomething("ok");}

  在DynamicProxy类中,有这样的方法,

    Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass(),handler);   该方法重新生成了一个对象,因为要使用代理!注意getInterfaces()这句话,查找所有该类的接口,然后实现接口中所有方法,当然,都是空方法,由谁来具体实现呢? 就是MyInvocationHandle这个对象。于是我们知道了,由InvocationHandler实现接口中所有方法,由其invoke具体接管所有方法的实现。

 

转载于:https://www.cnblogs.com/loveBolin/p/9697041.html

你可能感兴趣的文章
[ JAVA编程 ] double类型计算精度丢失问题及解决方法
查看>>
小别离
查看>>
微信小程序-发起 HTTPS 请求
查看>>
WPF动画设置1(转)
查看>>
基于node/mongo的App Docker化测试环境搭建
查看>>
java web 中base64传输的坑
查看>>
java 中的线程(一)
查看>>
秒杀9种排序算法(JavaScript版)
查看>>
Activiti入门 -- 环境搭建和核心API简介
查看>>
struts.convention.classes.reload配置为true,tomcat启动报错
查看>>
MySQL的并行复制多线程复制MTS(Multi-Threaded Slaves)
查看>>
好玩的-记最近玩的几个经典ipad ios游戏
查看>>
MySQL更改默认的数据文档存储目录
查看>>
PyQt5--EventSender
查看>>
Sql Server 中由数字转换为指定长度的字符串
查看>>
Java 多态 虚方法
查看>>
Unity之fragment shader中如何获得视口空间中的坐标
查看>>
万能的SQLHelper帮助类
查看>>
uboot分析:uboot的启动过程分析
查看>>
tmux的简单快捷键
查看>>