设计模式8:代理模式-动态代理

这篇具有很好参考价值的文章主要介绍了设计模式8:代理模式-动态代理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上一篇:设计模式8:代理模式-静态代理

如何理解“动态”这两个字?

“动态”的含义是代码生成代理类,一个代理类可以代理多个接口

动态区别于死板,静态代理中一个代理类只能代理一个接口,其他不同的接口,就需要再手写不同的代理类,这就很死板

动态代理类似于在安卓里面,我们常说的动态申请权限,其实就是用java或kotlin代码申请权限,而不是在AndroidManifest.xml文件里面写死一次可以申请一个或多个权限

上一篇:中,StationProxyStarProxy都是我们手写的代理类。动态代理可以自动生成代理类。

动态代理简单的代码实例

动态代理需要jdk中提供的两个类InvocationHandlerProxy,重写InvocationHandler接口实现代理方法,Proxy负责生成代理对象。
上篇文章中“明星代理”的例子,用动态代理实现如下:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface IStar {
    void sing(double money);
}

class StarImpl implements IStar {
    public void sing(double money) {
        System.out.println("唱歌,收入" + money + "元");
    }
}

class MyInvocationHandler implements InvocationHandler {
    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("请先预约时间");
        System.out.println("沟通出场费用");
        double money= (double) args[0];
        if (money < 100000) {
            System.out.println("对不起,出场费10w万以内不受理");
            return null;
        }

        System.out.println("经纪人抽取了"+ money * 0.2 + "代理费用");
        args[0] = money * 0.8;
        Object result = method.invoke(target, args);
        System.out.println("演唱完毕");
        return result;
    }
}

public class DynamicProxyExample {
    public static void main(String[] args) {
        //原始对象
        IStar mStar = new StarImpl();
        InvocationHandler handler = new MyInvocationHandler(mStar);

        //代理对象
        IStar proxyHello = (IStar) Proxy.newProxyInstance(
                mStar.getClass().getClassLoader(),
                mStar.getClass().getInterfaces(),
                handler
        );

        proxyHello.sing(200000);
    }
}

运行结果:

请先预约时间
沟通出场费用
经纪人抽取了40000.0代理费用
唱歌,收入160000.0元
演唱完毕

一个InvocationHandler代理多个接口

动态代理的核心优势就在于,一个代理类,可以代理多个接口。如下,演示的是一个代理handler,同时代理两个接口InterfaceA和InterfaceB:

package dynamic_proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface InterfaceA {
    void methodA();
}

interface InterfaceB {
    void methodB();
}

class ClassA implements InterfaceA {
    public void methodA() {
        System.out.println("执行methodA");
    }
}

class ClassB implements InterfaceB {
    public void methodB() {
        System.out.println("执行methodB");
    }
}

class MyInvocationHandler implements InvocationHandler {
    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("methodA")) {
            System.out.println("调用methodA之前");
            Object result = method.invoke(target, args);
            System.out.println("调用methodA之后");
            return result;
        } else if (method.getName().equals("methodB")) {
            System.out.println("调用methodB之前");
            Object result = method.invoke(target, args);
            System.out.println("调用methodB之后");
            return result;
        } else {
            throw new UnsupportedOperationException("Unsupported method: " + method.getName());
        }
    }
}

public class DynamicProxyExample {
    public static void main(String[] args) {


        InvocationHandler handlerA = new MyInvocationHandler(new ClassA());

        InterfaceA proxyA = (InterfaceA) Proxy.newProxyInstance(
                handlerA.getClass().getClassLoader(),
                new Class[]{InterfaceA.class},
                handlerA
        );
        proxyA.methodA();

        InvocationHandler handlerB = new MyInvocationHandler(new ClassB());
        InterfaceB proxyB = (InterfaceB) Proxy.newProxyInstance(
                handlerB.getClass().getClassLoader(),
                new Class[]{InterfaceB.class},
                handlerB
        );
        proxyB.methodB();
    }
}

代码执行结果:

调用methodA之前
执行methodA
调用methodA之后
调用methodB之前
执行methodB
调用methodB之后

动态代理大揭秘,带你彻底弄清楚动态代理!

有动态代理,为什么还要用Cglib代理?

动态代理只能把代理对象,赋值给接口,如上面的例子。不能把代理对象直接赋值一个普通类。而Cglib代理可以做到。具体怎么做的,下篇文章再讲。文章来源地址https://www.toymoban.com/news/detail-706693.html

到了这里,关于设计模式8:代理模式-动态代理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式8:代理模式-静态代理

    我尝试在JDK、Android SDK和一些出名的库中,寻找静态代理的源码,没能找到。如果有读者发现,欢迎评论或者私信我。 1. 售票代理 售票服务 站点售票 代理网点售票 2. 明星代理

    2024年02月11日
    浏览(35)
  • Java设计模式 (三) 代理设计模式

    什么是代理设计模式? 代理设计模式是一种结构型设计模式,它允许创建一个代理对象,用于控制对其他对象的访问。代理模式通常用于在访问对象时添加一些附加操作,而不是直接访问真实对象。代理模式可以在不改变原始类代码的情况下,通过引入代理类来增强功能。 代

    2024年02月12日
    浏览(41)
  • 设计模式|代理模式

    ​代理模式指为其他对象提供一种代理,以控制对这个对象的访问。在某些情况下,一个对象若不能直接引用另一个对象,而代理对象可以在客户端与目标对象之间起到中介的作用。 普通代理 普通代理模式是指在代理模式中,代理对象和真实对象都实现了相同的接口或继承

    2024年02月04日
    浏览(31)
  • 设计模式--代理模式

    笔记来源:尚硅谷Java设计模式(图解+框架源码剖析) 1)代理模式:为一个对象提供一个替身,以控制对这个对象的访问。即 通过代理对象访问目标对象 2)这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能 3)被代理的对象可以

    2024年02月10日
    浏览(33)
  • 【设计模式】-代理模式

    在软件开发中,经常遇到需要对某个对象进行控制或者监控的场景。而直接修改对象的代码可能使代码变得复杂且难以维护。这时,使用代理模式(Proxy Pattern)可以很好地解决这个问题。          代理模式是一种结构型设计模式, 通过引入一个代理对象来替代原始对象

    2024年02月13日
    浏览(34)
  • 设计模式详解-代理模式

    类型:结构型模式 实现原理:创建具有现有对象的对象 作用:为其他对象提供一种代理以控制对这个对象的访问。 解决的问题:由于对象的访问条件不一,直接访问对象会造成麻烦问题 解决问题的方法:增加中间层。 何时使用:想在访问一个类时做一些控制。 实现核心:

    2024年02月12日
    浏览(36)
  • 设计模式之代理模式

    当我们有对象因为安全性,不能直接对外暴露,或者是需要对对象的操作本身记录日志等信息时就可以考虑使用代理模式, 享元设计模式,包含如下元素: UML图如下: 另外,代理又分为静态代理和动态代理,静态代理就是在编译器已经确定的代理方式,即是硬编码到程序中

    2024年02月16日
    浏览(32)
  • 设计模式二:代理模式

    1、什么是动态代理 可能很多小伙伴首次接触动态代理这个名词的时候,或者是在面试过程中被问到动态代理的时候,不能很好的描述出来,动态代理到底是个什么高大上的技术。不方,其实动态代理的使用非常广泛,例如我们平常使用的 Spring 中的 @Transactional 注解,其依赖

    2024年02月20日
    浏览(44)
  • 设计模式 -- 代理模式

    月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂) 央是一片海洋,海乃百川,代表着一块海绵(吸纳万物) 泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出) 月央泽,学习的一种过程,从白纸-吸收各种知识-不断输入输出变成自己的内容 希望大家一起坚持这个过程,也同样希望大家

    2023年04月08日
    浏览(37)
  • 【设计模式】代理模式

    5.1.1 概述 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。 Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生成

    2024年02月15日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包