打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
设计模式之代理模式

定义 :

 为其他对象提供一种代理以控制对这个对象的访问

应用实例 :

1.windows里面的快捷方式 2.猪八戒去找高翠兰结果是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和      孙悟空都实现了这个接口,猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高  翠兰代理类。3.买火车票票不一定在火车站买,也可以去代售点4.一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账  号上资金的控制。 5.spring aop [详解](https://www.cnblogs.com/hongwz/p/5764917.html)

代理模式有几种: 虚拟代理,计数代理,远程代理,动态代理。主要分为两类, 静态代理和动态代理 。静态代理比较简单,是由程序员编写的代理类,并在程序运行前就编译好的,而不是由程序动态产生代理类,这就是所谓的静态。

静态代理:

/** * 卖票接口 *  * @author Administrator * */public interface Ticket {    void sellTicket();}/** * 火车站类 购票、改签、退票、 *  * @author Administrator * */public class Trainstation implements Ticket {    @Override    public void sellTicket() {        System.out.println("火车站售票~~~");    }    /**     * 改签     */    @SuppressWarnings("unused")    private void changeTicket() {        System.out.println("改签~");    }    /**     * 退票     */    @SuppressWarnings("unused")    private void backTicket() {        System.err.println("退票~");    }}/** * 黄牛代理 *  * @author Administrator * */public class CattleProxy implements Ticket {    private Ticket ticket;    public CattleProxy(Ticket ticket) {        this.ticket = ticket;    }    @Override    public void sellTicket() {        // TODO Auto-generated method stub        System.err.println("黄牛卖票");    }}public class ProxyTest {    public static void main(String[] args) {        // TODO Auto-generated method stub        Trainstation trainstation = new Trainstation();        CattleProxy cattleProxy = new CattleProxy(trainstation);        cattleProxy.sellTicket();    }

UML图

静态代理实现中,一个委托类对应一个代理类,代理类在编译期间就已经确定。

动态代理

动态代理中,代理类并不是在Java代码中实现,而是在运行时期生成,相比静态代理,动态代理可以很方便的对委托类的方法进行统一处理,如添加方法调用次数、添加日志功能等等,动态代理分为jdk动态代理和cglib动态代理,下面通过一个例子看看如何实现jdk动态代理。

1、定义业务逻辑

public interface Service {      //目标方法     public abstract void add();  } public class UserServiceImpl implements Service {      public void add() {          System.out.println("This is add service");      }  }

2、利用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口定义代理类的实现。

class MyInvocatioHandler implements InvocationHandler {    private Object target;    public MyInvocatioHandler(Object target) {        this.target = target;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("-----before-----");        Object result = method.invoke(target, args);        System.out.println("-----end-----");        return result;    }    // 生成代理对象    public Object getProxy() {        ClassLoader loader = Thread.currentThread().getContextClassLoader();        Class<?>[] interfaces = target.getClass().getInterfaces();        return Proxy.newProxyInstance(loader, interfaces, this);    }}

3、使用动态代理

public class ProxyTest {    public static void main(String[] args) {        Service service = new UserServiceImpl();        MyInvocatioHandler handler = new MyInvocatioHandler(service);        Service serviceProxy = (Service)handler.getProxy();        serviceProxy.add();    }}

执行结果:

-----before----- This is add service -----end----- 代理对象的生成过程由Proxy类的newProxyInstance方法实现,分为3个步骤: 1、ProxyGenerator.generateProxyClass方法负责生成代理类的字节码,生成逻辑比较复杂,有兴趣的同学可以继续分析源码 sun.misc.ProxyGenerator;

// proxyName:格式如 "com.sun.proxy.$Proxy.1"; // interfaces:代理类需要实现的接口数组; // accessFlags:代理类的访问标识; byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags); 2、native方法Proxy.defineClass0负责字节码加载的实现,并返回对应的Class对象。

Class clazz = defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); 3、利用clazz.newInstance反射机制生成代理类的对象;

优点:

  1. 职责清晰

    2.高扩展性

    3.智能化

    缺点:

1.由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。

2 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

使用场景:

按职责来划分,通常有一下使用场景:

1.远程代理 也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实

2.虚拟代理 根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象

3.Copy-on-Write代理

4.保护(Protect or Access)代理

5.Cache代理

6.防火墙(Firewall)代理

7.同步化(Synchronization)代理

7.智能引用(Smart Reference)代理

注意事项:

1.和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理迷失不能改变所代理类的接口

2.和装饰模式的区别:装饰模式为了增强功能,而代理模式是为了加以控制

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM) (清晰,浅显)
Java动态代理的两种实现方法
java反射机制与动态代理(三)
解读JDK的动态代理
struts2学习笔记(8)——拦截器原理
Spring的cglib代理!(给类生成子类)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服