Java中的代理机制

代理的概述

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

mybatis、spring都运用了代理机制

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

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

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

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

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

        • 代码展示

          • //首先,我们要写出联系代理类与目标类的桥梁,接口
            public interface BuyClothes {public void clothes(String size);
            }
            //然后我们写出目标类,这里用ClothedFactory为例
            public class ClothesFactory implements BuyClothes{@Overridepublic void clothes(String size) {System.out.println("已经为您定制好了大小为" + size +"的衣服");}
            }
            //写出静态代理类
            public class StaticProxy implements BuyClothes {private ClothesFactory clothesFactory = new ClothesFactory();//重写核心方法@Overridepublic 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.mzph.cn/diannao/45834.shtml

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

相关文章

【Python】日期和时间模块

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️Python】 文章目录 前言时间元组datetime 模块datetime类获取当前日期和时间 timedelta类日期和时间运算 strftime()方法格式化时间日期格式化符号 strptime()方法 Time 模块Time 模块内置函数Time 模…

编译适用于 Apple Silicon Macs 的 Chromium 教程

本教程将指导你如何在 Apple Silicon Macs 上编译 Chromium&#xff0c;包括所需的系统要求、工具安装、源码获取、环境配置、编译和运行步骤。 一、系统要求 Apple Silicon Mac&#xff08;如 M1、M2&#xff09;。安装 Xcode 和 macOS SDK&#xff08;通过 App Store 安装最…

AWDAWFAAFAWAWFAWF

创建两张表&#xff1a;部门&#xff08;dept&#xff09;和员工&#xff08;emp&#xff09; 创建视图v_emp_dept_id_1&#xff0c;查询销售部门的员工姓名和家庭住址 创建视图v_emp_dept&#xff0c;查询销售部门员工姓名和家庭住址及部门名称 创建视图v_dept_emp_count(dept…

Ubuntu使用Nginx部署uniapp打包的项目

使用uniapp导出web项目&#xff1a; 安装&#xff1a; sudo apt install nginx解压web.zip unzip web.zip移动到/var/www/html目录下&#xff1a; sudo cp -r ~/web/h5/ /var/www/html/重启Nginx&#xff1a; sudo service nginx restart浏览器访问&#xff1a;http://19…

Java高频面试基础知识点整理4

干货分享&#xff0c;感谢您的阅读&#xff01;背景​​​​​​高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09; 最全文章见&#xff1a;Java高频面试基础知识点整理 &#xff08;一&#xff09;Java基础高频知识考点 针对人员&#xff1a; 1.全部人员都…

算法学习笔记(8.4)-完全背包问题

目录 Question&#xff1a; 图例&#xff1a; 动态规划思路 2 代码实现&#xff1a; 3 空间优化&#xff1a; 代码实现&#xff1a; 下面是0-1背包和完全背包具体的例题&#xff1a; 代码实现&#xff1a; 图例&#xff1a; 空间优化代码示例 Question&#xff1a; 给定n个物品…

Tomcat组件概念和请求流程

Tomcat:是一个Servlet容器(实现了Container接口)&#xff0c;容器分层架构从上到下分为。Engine(List<Host>)->Host(List<Context>)->Context(List<Wrapper>)->Wrapper(List<Servlet>); Engine:引擎&#xff0c;Servlet 的顶层容器&#xff0…

UML建模案例分析-类图中的关系

概要 类图之间的关系比较多&#xff0c;绝大多数情况下重点关注的还是关联关系、组合、聚合这三种&#xff0c;最终是如何对应到代码上的。 例子 以订单为例&#xff1a;订单和订单项之间是组合关系&#xff0c;这和数据库实体之间不一样。数据库实体有主外键&#xff0c;开…

Java聚合跑腿系统对接云洋聚合跑腿系统源码低价快递小程序APP公众号源码

一站式解决方案 &#x1f680;引言&#xff1a;跑腿服务的市场需求与聚合趋势 在快节奏的现代生活中&#xff0c;跑腿服务成为了越来越多人的选择。为了满足这一市场需求&#xff0c;各大跑腿平台纷纷涌现。然而&#xff0c;如何将这些平台进行有效整合&#xff0c;提供更为便…

比特币交易繁忙的一天

早晨:市场开盘与准备工作 6:00 AM - 全球市场监测 交易员们早早起床,开始监测全球市场动态,尤其是亚洲市场的动向。通过查看新闻、分析报告和市场数据,了解可能影响比特币价格的因素。 7:00 AM - 团队会议 召开晨会,讨论当天的交易策略。团队分析前一天的交易情况,评…

HTML网页大设计-家乡天水

代码下载: https://pan.quark.cn/s/6bad4cfaefda

Windows下vscode配置C++环境

一、vscode下载及安装 vscode官网 选安装位置。 勾选这几项。 1.vscode界面中文配置 &#xff08;1&#xff09;点击扩展小图标&#xff0c;搜索插件&#xff0c;找到插件Chinese (Simplified) (简体中文) Language Pack&#xff0c;点击install。 &#xff08;2&#xf…

【vue组件库搭建07】Vitest单元测试

vitest官网 vue-test-utils 我们的测试框架选择的是 Vitest 和 vue-test-utils。两者的关系为&#xff1a; Vitest 提供测试方法&#xff1a;断言、Mock 、SpyOn 等方法。vue-test-utils: 挂载和渲染组件&#xff1a; Vue Test Utils 允许您在隔离中挂载组件&#xff0c;这意…

实用机器学习(快速入门)

前言 因为需要机器学习的助力&#xff0c;所以&#xff08;浅浅&#xff09;进修了一下。现在什么东西和AI结合一下感觉就好发文章了&#xff1b;我看了好多学习视频&#xff0c;发现机器学习实际上是数学&#xff0c;并不是常规的去学习代码什么的&#xff08;虽然代码也很简…

我应该使用 Pinia 还是 Vuex?

大家好,我是CodeQi! 一位热衷于技术分享的码仔。 当项目逐渐变大时,状态管理的问题开始显现了出来。这时,两个强大的状态管理工具:Vuex 和 Pinia。该选择哪一个呢? 今天带各位大佬对比下两者的优势在何处,以及如何选择合适的状态管理库! 什么是 Vuex? Vuex 是 Vue.j…

时间管理的6张清单:做个时间清单控,提高时间颗粒度!

时间管理管理的到底是什么&#xff1f;我觉得其根本就是时间的颗粒度。这与大多数行业精英的时间管理不谋而合&#xff0c;也就是身段越高&#xff0c;时间管理的颗粒度越高。比尔盖茨的颗粒度是5分钟&#xff0c;精确到与人握手&#xff0c;按秒来安排&#xff01;接下来&…

Amesim-帮助文件翻译与总结-tigger(滞环)

元件应用说明 滞环一般应用于控制策略制定&#xff0c;该原件类似于一个开关&#xff0c;当输入值大于设置的high input threshold Value时输出high out value&#xff1b;小于low input threshold value时输出low output value。若输出值在high input threshold Value与low i…

大模型应用中CoT(思维链)技术详细介绍

大模型应用中CoT&#xff08;思维链&#xff09;技术详细介绍 1. 背景 在自然语言处理&#xff08;NLP&#xff09;领域中&#xff0c;尤其是语言模型&#xff08;如GPT-3, BERT等&#xff09;的应用中&#xff0c;理解和推理复杂的文本信息变得越来越重要。Chain-of-Thought…

01. 课程简介

1. 课程简介 本课程的核心内容可以分为三个部分&#xff0c;分别是需要理解记忆的计算机底层基础&#xff0c;后端通用组件以及需要不断编码练习的数据结构和算法。 计算机底层基础可以包含计算机网络、操作系统、编译原理、计算机组成原理&#xff0c;后两者在面试中出现的频…

走进linux

1、为什么要使用linux 稳定性和可靠性&#xff1a; Linux内核以其稳定性而闻名&#xff0c;能够持续运行数月甚至数年而不需要重新启动。这对于服务器来说至关重要&#xff0c;因为它们需要保持长时间的稳定运行&#xff0c;以提供持续的服务 安全性&#xff1a; Linux系统…