代理模式代理模式

news2024/12/23 20:53:31

目录

1、使用场景

2、静态代理

3、动态代理

JDK动态代理

CGlib 动态代理实现


1、使用场景

使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。

2、静态代理

NO.1 抽象接口:定义视频播放器接口Player

public interface Player {
    void loadVideo(String filename);
    void playVideo(String filename);
}

NO.2 真实类:定义接口实现类VPlayer

public class VPlayer implements Player {
    @Override
    public void loadVideo(String filename) {
        System.out.println("加载MP4视频文件:"+filename);
    }

    @Override
    public void playVideo(String filename) {
        System.out.println("播放MP4视频:"+filename);
    }
}

NO.3 代理类:定义代理类VPlayerProxy,实现同样的接口,并且引入目标对象

public class VPlayerProxy implements Player {

    private Player player;

    public VPlayerProxy(Player player) {
        this.player = player;
    }

    @Override
    public void loadVideo(String filename) {
        player.loadVideo(filename);
    }

    @Override
    public void playVideo(String filename) {
        player.playVideo(filename);
    }
}

NO.4 客户端调用

public class Client1 {
    public static void main(String[] args) {
        //直连方式
        Player vplay=new VPlayer();
        vplay.playVideo("aaa.mp4");
        System.out.println();

        //代理方式
        Player proxy=new VPlayerProxy(vplay);
        proxy.loadVideo("aaa.mp4");
        proxy.playVideo("aaa.mp4");

    }
}

3、动态代理

JDK动态代理

JDK动态代理是基于接口实现的代理,只能代理实现了接口的类。

在运行时动态生成一个代理对象,,同时还可以在方法调用前后执行额外的增强处理。JDK动态代理通过反射机制实现代理功能,其原理分为以下几个步骤:

(1)、创建实现InvocationHandler接口的代理类工厂:在调用Proxy类的静态方法newProxyInstance时,会动态生成一个代理类。
(2)、在代理对象的方法被调用时,JVM会自动调用代理类的invoke方法。在invoke方法中,可以根据需要执行各种逻辑,比如添加日志、性能统计、事务管理等。
(3)、invoke方法调用:在invoke方法中,通过反射机制调用目标对象的方法,并返回方法的返回值。在调用目标对象的方法前后,可以执行额外的逻辑。

通用实现代码

public class JDKProxyFactory implements InvocationHandler {

    //需要被代理的对象
    private Object object;

    public JDKProxyFactory(Object object) {
        this.object = object;
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy(){
        return (T) Proxy.newProxyInstance(
                Thread.currentThread().getContextClassLoader(),//当前线程的上下文ClassLoader
                object.getClass().getInterfaces(), //代理需要实现的接口
                this); // 处理器自身
    }
	
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
		//进行方法匹配,调用对应方法名的方法
        if ("loadVideo".equals(method.getName())) {
            result=method.invoke(object, args);
        }

        if ("playVideo".equals(method.getName())) {
            System.out.println("前置增强");
            result=method.invoke(object, args);
            System.out.println("后置增强");
        }
        return result;
    }
}

客户端调用

public class Client2 {
    public static void main(String[] args) {
        Player player=new VPlayer();
        Player proxy=new JDKProxyFactory(player).getProxy();
        proxy.loadVideo("aaa.mp4");
        proxy.playVideo("aaa.mp4");

/*      或者
        Player p=new VPlayer();
        Player o = (Player) Proxy.newProxyInstance(
                p.getClass().getClassLoader(),
                p.getClass().getInterfaces(),
                new VPlayerProxyFactory(p)
        );
        o.loadVideo("aaaa.mp4");
*/
    }
}

CGlib 动态代理实现

CGlib方式是基于继承实现的代理,它不是指真实类需要继承某个父类,而是生成的代理类作为真实类的子类去代理父类,即代理类继承自真实类。这种方式不需实现接口,可以作为JDK代理方式的补充方案。

CGLIB(Code Generation Library)可以在运行时动态生成目标类的子类作为代理类,并覆盖其中的方法来实现代理功能。与Java自带的JDK动态代理不同,CGlib动态代理可以代理没有实现接口的类。其原理分为以下几个步骤:

(1)、创建Enhancer对象:Enhancer是CGLIB库中用于动态生成子类的主要类。通过创建Enhancer对象并设置需要代理的目标类、拦截器等参数,可以生成一个代理类。

 (2)、调用代理对象:通过调用代理对象的方法,会触发拦截器的intercept方法。在intercept方法中,可以根据需要执行各种逻辑,比如添加日志、性能统计、事务管理等。

单独定义一个没有接口的真实类APlayer

//音频播放器
public class APlayer {
    public void loadAudio(String filename) {
        System.out.println("加载MP3音频文件:"+filename);
    }

    public void playAudio(String filename) {
        System.out.println("播放MP3:"+filename);
    }
}

通用实现代码

public class CglibProxyFactory implements MethodInterceptor {

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> clazz) {
        Enhancer en = new Enhancer();
        //设置代理的父类
        en.setSuperclass(clazz);
        //设置方法回调
        en.setCallback(this);
        //创建代理实例
        return (T)en.create();
    }

    @Override
    //参数中的object是目标对象,method和args是目标对象的方法和参数,methodProxy是方法代理
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object result = null;

        if ("loadAudio".equals(method.getName())) {
            //通过继承的方法实现代理,因此这里调用invokeSuper
            result = methodProxy.invokeSuper(object, args);
        }
        if ("playAudio".equals(method.getName())) {
            result = methodProxy.invokeSuper(object, args);
        }
        return result;
    }
}

客户端调用

public class Client3 {
    public static void main(String[] args) {
        APlayer aplayer=new APlayer();
        APlayer proxy = new CglibProxyFactory().getProxy(aplayer.getClass());
        //验证代理类的父类
        System.out.println("代理类的父类:"+proxy.getClass().getSuperclass().getSimpleName());
        System.out.println();

        proxy.loadAudio("荷塘月色.mp3");
        proxy.playAudio("荷塘月色.mp3");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1153860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据之路-日志采集

数据采集作为大数据体系中的第一环节&#xff0c;对如何全面、高性能、规范完成海量数据的采集&#xff0c;并将其传输到大数据平台。 1.浏览器的页面日志采集 1.1 页面浏览日志采集流程 页面浏览日志是最基础的互联网日志&#xff0c;其中页面浏览量&#xff08;PageView&am…

短期经济波动:均衡国民收入决定理论(一)

宏观经济学讲义 10 短期经济波动&#xff1a;均衡国民收入决定理论(一) 文章目录 10 短期经济波动&#xff1a;均衡国民收入决定理论(一)[toc]1 均衡国民收入决定1.1 均衡国民收入决定的不同理论1.2 两部门经济&#xff1a;有效需求原理和框架1.2.1 模型假设1.2.2 模型推导1.2…

【零基础抓包】Fiddler超详细教学(一)

​Fiddler 1、什么是 Fiddler? Fiddler 是一个 HTTP 协议调试代理工具&#xff0c;它能够记录并检查所有你的电脑和互联网之间的 HTTP 通讯。Fiddler 提供了电脑端、移动端的抓包、包括 http 协议和 https 协议都可以捕获到报文并进行分析&#xff1b;可以设置断点调试、截取…

期中成绩发布一对一查询

亲爱的老师们&#xff01;我知道您在期中考试后忙碌而又紧张&#xff0c;不仅要准备试卷分析&#xff0c;还要面对学生和家长的询问。现在&#xff0c;我为您带来了一款一对一成绩查询系统&#xff0c;让您的工作变得更简单、更高效&#xff01; 什么是成绩查询系统&#xff1f…

一个小妙招从Prompt菜鸟秒变专家!加州大学提出PromptAgent,帮你高效使用ChatGPT!

夕小瑶科技说 原创 作者 | 谢年年、王二狗 有了ChatGPT、GPT4之后&#xff0c;我们的工作学习效率得到大大提升&#xff08;特别在凑字数方面୧(๑•̀◡•́๑)૭&#xff09;。 作为一个工具&#xff0c;有人觉得好用&#xff0c;自然也有人觉得难用。 要把大模型用得6&am…

518抽奖软件,为什么说比别的抽奖软件更美观精美?

518抽奖软件简介 518抽奖软件&#xff0c;518我要发&#xff0c;超好用的年会抽奖软件&#xff0c;简约设计风格。 包含文字号码抽奖、照片抽奖两种模式&#xff0c;支持姓名抽奖、号码抽奖、数字抽奖、照片抽奖。(www.518cj.net) 精致美观功能 字体平滑无锯齿图片放大后清晰…

SCADA在污水和供水系统解决方案

1. 引言 随着城市化的不断发展&#xff0c;污水和供水系统的管理变得越来越重要。为了提高运营效率和监控系统状态&#xff0c;许多污水处理厂开始使用SCADA系统。 SCADA系统具有实时数据采集、监控和控制功能&#xff0c;可以帮助污水处理厂运营人员实时了解系统的运行情况&…

Google Play优化之如何增强应用的吸引力

视觉元素&#xff0c;在增强应用在Google Play上的吸引力方面发挥着巨大作用。应用程序的图标、屏幕截图和宣传视频&#xff0c;构成了应用程序商店优化过程的关键部分。 1、图标是用户遇到的第一个视觉元素。 精心设计的图标可以有效地代表应用程序的用途&#xff0c;可以显著…

LeetCode | 26. 删除有序数组中的重复项

LeetCode | 26. 删除有序数组中的重复项 OJ链接 这里的非递增是什么意思&#xff1f; 就是反过来的&#xff0c;递减&#xff0c;不能说是乱序~~也就是后一个比前一个小也就是和非递减等价&#xff0c;后一个比前一个大~~ 所以非递增和非严格递增是不一样的~~ 这里本质上的…

亚马逊云科技为奇点云打造全面、安全、可扩展的数据分析解决方案

刘莹奇点云联合创始人、COO&#xff1a;伴随云计算的发展&#xff0c;数据技术也在快速迭代&#xff0c;成为客户迈入DT时代、实现高质量发展的关键引擎。我们很高兴能和云计算领域的领跑者亚马逊云科技一同&#xff0c;不断为客户提供安全可靠的产品与专业的服务。 超过1500家…

外汇天眼:GOMAX──假网友热心教投资,高返利活动骗入金

在通讯科技如此发达的今日&#xff0c;人们愈来愈习惯透过网路交友&#xff0c;寻找志同道合的伙伴&#xff0c;甚至发展一段亲密关系。 然而&#xff0c;近年来假交友诈骗十分猖獗&#xff0c;至今已造成许多民众极大的财务损失&#xff0c;成为无法忽视的社会问题。 不久前&a…

kubectl资源管理命令---声明式

目录 一、yaml和json介绍 1、yuml语言介绍 2、k8s支持的文件格式 二、声明式对象管理 1、deployment.yaml文件详解 2、Pod yaml文件详解 3、Service yaml文件详解 三、编写资源配置清单 1、 编写yaml文件 2、 创建并查看pod资源 3、创建service服务对外提供访问并测试…

从零开始学习Java:如何成为一名Java开发者并找到工作

文章目录 &#x1f31f; JavaSE&#x1f31f; JavaWeb&#x1f31f; 多线程&#x1f31f; 主流框架&#x1f31f; Redis缓存&#x1f31f; 消息中间件&#x1f31f; 全文搜索&#x1f31f; MySQL&#x1f31f; Mongodb&#x1f31f; 开发工具&#x1f31f; 模板引擎&#x1f31…

2023年是5G-A标准制定关键年 华为实现5G-A重大突破

5G商用四年&#xff0c;2023年5G应用项目已经达到10万个&#xff0c;5G向千行百业渗透的同时&#xff0c;也在向5G-Advanced&#xff08;下简称5G-A&#xff09;演进。 10月20日&#xff0c;在工业和信息化部主办的2023年中国5G发展大会上&#xff0c;由IMT-2020&#xff08;5G…

Yusi技术资讯博客wordpress模板

Yusi技术资讯博客wordpress模板&#xff0c;从第一感觉看上去&#xff0c;两栏结构直接将网站的内容展现&#xff0c;以红白灰色调搭配&#xff0c;一种低调协调的风格&#xff0c;喜欢该wordpress主题的朋友可以下载试试。 下载地址&#xff1a;https://bbs.csdn.net/topics/…

在Instagram进行kol营销之后要如何去后续维护

在网红经济盛行的如今&#xff0c;学会利用网红的影响力来推广品牌是营销中很重要的一个形式。企业要把握这个风口&#xff0c;承接这些网红带来的流量之后&#xff0c;牢牢掌握&#xff0c;及时开展后续的营销活动&#xff0c;这样才能实现高转化&#xff0c;成为网红经济下的…

python按照windows或者Ubuntu的文件夹中文件的顺序读取文件

摘要 在使用python读取文件的时候&#xff0c;发现python读取文件的顺序和文件夹中的顺序不一致&#xff0c;这时候应该怎么办呢&#xff1f; 解决方法 使用os_sorted库&#xff0c;安装方式&#xff1a; pip install natsort使用方法&#xff1a; from natsort import os…

【JavaSE专栏56】Java面向对象编程:深入理解类、对象、属性和方法的核心概念

Java面向对象编程&#xff1a;深入理解类、对象、属性和方法的核心概念 &#x1f4da;&#x1f9ec;&#x1f4bb; 摘要引言1. Java中的类和对象 &#x1f4da;&#x1f9ec;1.1 什么是Java类和对象&#xff1f; &#x1f914;1.2 类和对象在面向对象编程中的作用 &#x1f3af…

centos 7 kafka2.6单机安装及动态认证SASL SCRAM配置

目录 1.kfaka安装篇 1.1 安装jdk 1.2安装kafka 2.安全篇 2.1 kafka安全涉及3部份&#xff1a; 2.2 Kafka权限控制认证方式 2.3 SASL/SCRAM-SHA-256 配置实例 2.3.1 创建用户 2.3.2 创建 JAAS 文件及配置 3.测试 3.1 创建测试用户 3.2 配置JAAS 文件 3.2.1 生产者配…

关于息肉检测和识别项目的总结

前言 整体的思路&#xff1a;首先息肉数据集分为三类&#xff1a; 1.正常细胞 2. 增生性息肉 3. 肿瘤要想完成这个任务&#xff0c;首先重中之重是分割任务&#xff0c;分割结果的好坏&#xff0c; 当分割结果达到一定的准确度后&#xff0c;开始对分割后的结果进行下游分类…