Java中的代理机制

代理的概述

代理:给目标对象提供一个代理对象,并且由代理对象控制着对目标对象的引用(跟多态一样)

mybatis、spring都运用了代理机制

跳过创建类的过程,直接产生对象

简单来说,我们使用代理对象来代替对真实对象的访问,这样就可以在不修改原目标对象的前提下,提供额外的操作功能,扩展目标对象的功能

通俗的说,对象嫌身上干的事情太多,就需要通过代理来转移部分职责(意思就是尽量保证单一职责)。同时,对象有什么方法,代理就一定要有对应的方法

代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作

  • 代理的实现
    • 基于JDK的代理
      • 静态代理
        • 在静态代理中,我们对目标对象的每个方法的增强都是手动完成的(后面会具体演示代码),非常不灵活(比如接口一旦新增加方法,目标对象和代理对象都要进行修改)且麻烦(需要对每个目标类都单独写一个代理类)。从 JVM 层面来说, 静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的 class 文件。

        • 代码展示

          • //首先,我们要写出联系代理类与目标类的桥梁,接口
            public interface BuyClothes {
                public void clothes(String size);
            }
            //然后我们写出目标类,这里用ClothedFactory为例
            public class ClothesFactory implements BuyClothes{
                @Override
                public void clothes(String size) {
                    System.out.println("已经为您定制好了大小为" + size +"的衣服");
                }
            }
            //写出静态代理类
            public class StaticProxy implements BuyClothes {
                private ClothesFactory clothesFactory = new ClothesFactory();
            
                //重写核心方法
                @Override
                public void clothes(String size) {
                    //代理类与目标类建立起了桥梁
                    clothesFactory.clothes(size);
                }
            }
            //模拟用户方面
            public class Test {
                public static void main(String[] args) {
                    StaticProxy staticProxy = new StaticProxy();
                    //此处,用户访问目标类的路径:用户-->代理类StaticProxy---(以共同接口BuyClothes为中间节点)--->目标类ClothesFactory-->完成clothes()方法
                    staticProxy.clothes("XXXL");
                }
            }
      • 动态代理:一个代理类代理多个目标类
        • 在静态代理中,我们代理的仅仅是一个方法,但是在平时,一个类通常会有很多方法,对应的对象也会调用多个类,那么此时如果还是用静态代理,就会特别麻烦,所以就有了动态代理

        • JDK中提供了一个方法,可以动态的实现新增的接口,该方法是Proxy.newProxyInstance() 

    • 基于CGLIB的动态代理
      • cglib是第三方的工具库, 创建代理对象
      • cglib的原理是继承, cglib通过继承目标类,创建它的子类,在子类中重写父类中同名的方法, 实现功能的修改
      • 因为cglib是继承,重写方法,所以要求目标类不能是final的, 方法也不能是final的
      • 不需要目标类有接口,通过继承就可以
      • 经常用于框架中,例如Spring(SpringAOP)  
    • 基于JDK的动态代理
      • 要求目标与代理类实现相同的接口,若目标类不存在接口,则无法使用该方式(要求有接口)
      • 使用java反射包中的类和接口实现动态代理的功能
      • 反射包 java.lang.reflect , 里面有三个类 : InvocationHandler , Method, Proxy
        • InvocationHandler :接口(调用处理器),里面就一个方法invoke(),用来表示代理类用来干什么
          • invoke:表示代理对象要执行的功能代码,即想要代理的功能
          • 代理类完成的功能
            • 调用目标方法,执行目标方法的功能
            • 功能增强,在目标方法调用时,增加功能  
          • invoke方法原型
            • public Object invoke(Object proxy, Method method, Object[] args)
            • 参数列表
              • Object proxy:jdk创建的代理对象,无需赋值

              • Method method:目标类中的方法,jdk提供method对象,无需赋值

              • Object[] args:目标类中的方法参数,jdk提供   

            • 使用:创建类实现InvocationHandler接口,重写invoke方法
        • Method类:表示方法,确切的说就是目标类中的方法  
          • 作用:通过Method可以执行某个目标类的方法,Method.invoke() (注意,此处的invoke跟InvocationHandler中的invoke不同,这里的invoke是反射机制中的Method类中的方法,即method.invoke(Object,args))
        • Proxy类:核心的对象,创建代理对象
          • 之前创建对象都是new的方法,在动态代理中,使用Proxy的方法来创建

          • 方法:newProxyInstance()

            • 是一个静态方法,作用就是创建代理对象

            • 方法原型

              • public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
              • 参数列表

                • ClassLoader loader:类加载器,向内存中加载对象,使用反射获取对象的classLoader

                • Class<?>[] interfaces:目标对象实现的接口(因为JDK的动态代理就是通过接口实现的),通过反射获取

                • InvocationHandler h:自己写的代理类要完成的功能(上述的InvocationHandler中的invoke)

                • 返回值就是代理对象

      • JDK动态代理的实现

        • 创建接口,定义目标类要完成的功能

        • 创建目标类实现接口

        • 创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能

          • 调用目标方法

          • 增强功能

        • 使用Proxy类的静态方法,创建代理对象,并把返回值转为接口类型

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【《无主之地3》风格角色渲染在Unity URP下的实现_角色渲染(第四篇) 】

文章目录 概要描边问题外秒变分叉解决办法1:测试效果如下:外秒变分叉解决办法2:URP管线下PBR渲染源码关键词解释:完整shader代码如下:URP管线下二次元皮肤渲染源码URP管线下二次元头发渲染源码简要介绍文章的目的、主要内容和读者将获得的知识。 概要 提示:《无主之地3》…

华贝甄选干细胞科技,揭秘生命修复的奥秘

在探索生命奥秘的漫漫征途中&#xff0c;华贝甄选凭借干细胞科技的神奇力量&#xff0c;为您点亮健康与活力的希望之光。 我们深知&#xff0c;细胞是生命的基石&#xff0c;而干细胞则是这基石中蕴含的无限潜能。华贝甄选精心打造的干细胞疗法&#xff0c;如同神奇的魔法&…

【排序算法】插入排序(希尔排序)

目录 一.直接插入排序 1.基本思想 2.实现 3.特性 1.效率 2.时间复杂度&#xff1a;O(N^2) 3.空间复杂度&#xff1a;O(1) 4.稳定性&#xff1a;稳定 二.希尔排序 1.基本思想 2.实现 3.特性 1.效率 2.时间复杂度&#xff1a;O(N^1.3) ​编辑 3.空间复杂度&#xff…

《植物大战僵尸杂交版》2.2:新版本体验与下载指南

作为《植物大战僵尸》系列的忠实粉丝&#xff0c;我最近发现了一款令人兴奋的改版游戏——《植物大战僵尸杂交版》2.2。这款游戏不仅保留了原作的经典元素&#xff0c;还加入了一些创新的玩法&#xff0c;让我忍不住想要分享给大家。 2.2版本新体验 新僵尸登场 最新版本中&am…

vue3 - vue项目自动检测更新

GitHub Demo 地址 在线预览 web项目当页面检测到需要更新&#xff0c;然后弹框提示是否更新&#xff08;刷新页面&#xff09;这种可以通过纯前端实现也可以通过接口实现 接口实现&#xff1a;通过调用接口轮询和本地的版本号比较&#xff0c;检查是否需要弹框提示更新纯前端实…

移动应用稳定性测试

移动应用稳定性测试 使用Monkey等工具进行移动应用稳定性测试是一种常见的自动化测试方法。Monkey工具可以自动生成各种随机事件来模拟用户操作&#xff0c;从而测试应用在不同情况下的表现。在执行monkey命令后&#xff0c;主要观察以下的结果信息来评估移动应用的稳定性。 崩…

【PyQt】

PyQT5线程基础&#xff08;2&#xff09; 线程案例案例一案例二 线程案例 案例一 案例一代码通过线程实现点击按钮向线程传输地址&#xff0c;程序等待20秒后&#xff0c;返回结果。 通过QtDesigner创建如下图所示的界面ui&#xff0c;并用UIC工具转成对应的py文件。 main文…

作业一:ER图 作业:二QQ项目思路 作业三:实现QQ的登录与注册界面

一、ER图 二、QQ项目思路&#xff1a;客户端功能&#xff0c;服务器端功能的实现 1.登录注册&#xff1a; 将基本信息如手机号码&#xff0c;验证码&#xff0c;还有已有的账号及账号相关信息等存入数据库中&#xff0c;登录方式为账号密码登录&#xff0c;还有忘记密码用邮箱…

深度学习DeepLearning多元线性回归 学习笔记

文章目录 多维特征变量与术语公式多元线性回归正规方程法Mean normalizationZ-score normalization设置合适的学习率Feature engineering 多维特征 变量与术语 列属性xj属性数n x ⃗ \vec{x} x (i)行向量某个值 x ⃗ j i \vec{x}_j^i x ji​上行下列均值μ标准化标准差σsigm…

为什么渲染农场渲染的是帧,而不是视频?

在3D动画产业的壮阔画卷中&#xff0c;渲染农场作为幕后英雄&#xff0c;以其庞大的计算能力支撑起无数视觉奇观的诞生。这些由高性能计算机集群构成的系统&#xff0c;通过独特的逐帧渲染策略&#xff0c;解锁了单机难以企及的创作自由与效率。本文将深入剖析这一策略背后的逻…

odoo 自定义菜单模型等进行报表输出

由于个性化需求&#xff0c;要定义不同报表不同条件搜索&#xff0c; 所以自定义有如下&#xff1a; 模型字段权限菜单 功能如下&#xff1a; 启用&#xff1a;创建新菜单、form视图、action动作 前提&#xff1a;模型已经创建好&#xff0c; 禁用&#xff1a;对菜单进行归档…

PMP–计算--图示

文章目录 概念基准绩效预测 公式 概念 基准绩效 最常见的基准是成本和进度。跟踪范围或技术基准的项目可以使用可交付物测量指标中的信息。 大多数进度测量指标会根据以下相关的计划绩效来跟踪实际绩效&#xff1a; ▶ 开始日期和完成日期。将实际开始日期与计划开始日期进行…

基于术语词典干预的机器翻译挑战赛笔记Task1 跑通baseline

#AI夏令营 #Datawhale #夏令营 Step1&#xff1a;报名赛事&#xff01;(点击即可跳转) 赛事链接&#xff1a;https://challenge.xfyun.cn/h5/detail?typerole-element-extraction&chdw24_y0SCtdhttps://challenge.xfyun.cn/topic/info?typemachine-translation-2024&…

【Linux杂货铺】2.进程优先级

1.进程优先级基本概念 进程优先级是操作系统中用于确定进程调度顺序的一个指标。每个进程都会被分配一个优先级&#xff0c;优先级较高的进程会在调度时优先被执行。进程优先级的设定通常根据进程的重要性、紧急程度、资源需求等因素来确定。操作系统会根据进程的优先级来决定进…

如何评估媒体邀约宣传的效果

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 评估媒体邀约宣传的效果是一个系统而全面的过程&#xff0c;它涉及多个维度的考量和分析。 一、受邀媒体的出席率&#xff1a; 1.受邀媒体出席率直观反映了媒体邀约的效果&#xff1b; …

基于SpringBoot+MySQL的租房项目+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

LLM-阿里云 DashVector + ModelScope 多模态向量化实时文本搜图实战总结

文章目录 前言步骤图片数据Embedding入库文本检索 完整代码 前言 本文使用阿里云的向量检索服务&#xff08;DashVector&#xff09;&#xff0c;结合 ONE-PEACE多模态模型&#xff0c;构建实时的“文本搜图片”的多模态检索能力。整体流程如下&#xff1a; 多模态数据Embedd…

Camera Raw:蒙版 - 选择主体、天空、背景、对象、人物

Camera Raw “蒙版”模块提供了五种基于 AI 技术自动选择并创建蒙版的方法&#xff0c;帮助用户更高效地进行选择和调整特定照片区域。 它们是&#xff1a;选择主体、选择天空、选择背景、选择对象以及选择人物。 ◆ ◆ ◆ 选择主体 Select Subject 基于 AI 技术自动分析并选…

昇思25天学习打卡营第1天|初步了解

1在昇思平台上申请过相关资源之后&#xff0c;将示例代码粘贴到输入框内。可以在下图中创建一个新的文档。 2不过初次运行的时候会遇到一个问题&#xff0c;点击运行的时候会出现新的输入框&#xff0c;而不是直接运行。遇到此问题等待就可以了&#xff0c;或者稍微等一下再运…

在分布式环境中,怎样保证 PostgreSQL 数据的一致性和完整性?

文章目录 在分布式环境中保证 PostgreSQL 数据的一致性和完整性一、数据一致性和完整性的重要性二、分布式环境对数据一致性和完整性的挑战&#xff08;一&#xff09;网络延迟和故障&#xff08;二&#xff09;并发操作&#xff08;三&#xff09;数据分区和复制 三、保证 Pos…