静态代理、动态代理与Mybatis的理解

Mybatis---代理设计模式(超详细) 本文主要讲解Mybatis---代理设计模式,从静态代理、动态代理、cglib代理等等帮助深刻理解 阅读详情

静态代理、动态代理与Mybatis的理解

这里的 代理 与设计模式中的代理模式密切相关,代理模式的主要作用是为其他对象提供一种控制对这个对象的访问方法,即在一个对象不适合或者不能直接引用另一个对象时,代理对象充当中介的作用。

现实生活中比较贴切的例子比如租房,被代理对象就是房东,代理对象就是中介,使用者就是租客,租客通过中介向房东租赁房屋,即使用者通过代理对象访问被代理对象。

一、直接调用

  • 一般我们通过new关键字初始化对象来调用类中的方法

  • 如下代码,创建Human接口,Student类实现了Human接口,在main函数中,通过new关键字来初始化Student对象来实现对Student类中 say() 方法的调用

interface Human{
    public void say();
}

class Student implements Human{
    @Override
    public void say() {
        System.out.println("I'm a Student");
    }
}

public class ProxyTest {
    public static void main(String[] args) {
        Human human = new Student();
        human.say();
    }
}

//输出
//I'm a Student

二、静态代理

实现静态代理有以下三个步骤:

  • 创建接口,通过接口来实现对象的代理

  • 创建该接口的实现类

  • 创建Proxy代理类来调用我们需要的方法

interface Human{
    public void say();
}

class Student implements Human{

    @Override
    public void say() {
        System.out.println("I'm a Student");
    }
}

class StudentProxy implements Human{
    private Student student;

    public StudentProxy(){}

    public StudentProxy(Student student){
        this.student = student;
    }
    
    private void begin(){
        System.out.println("Begin");
    }
    
    private void end(){
        System.out.println("End");
    }
    
    @Override
    public void say() {
        begin();
        student.say();
        end();
    }
}

public class ProxyTest {
    public static void main(String[] args) {
        Student student = new Student();
        StudentProxy studentProxy = new StudentProxy(student);
        studentProxy.say();
    }
}

//输出
//Begin
//I'm a Student
//End

在上述代码中,我们在没有修改Student类中 say() 方法的情况下,实现了在原来的 say() 方法前后分别执行 sayHello() 和 sayBye() 方法。由此引出代理模式的主要作用:

  • 在不修改被代理对象的情况下,实现对被代理对象功能的增强

同时,静态代理也存在一些比较致命的缺点。想象这样一个场景:若新增一个Worker类实现了Human接口,我们应该如何去代理这个Worker类?比较容易想到的方法是扩大 StudentProxy 的代理范围,然后将Worker当作参数传入 StudentProxy ,然后继续使用 StudentProxy 类代理Worker对象。这样实现功能是没有问题的,但会存在如下问题:

  • 当Human接口的实例中方法增加时,代理类中代码会变得非常冗长
  • 当有其他不属于Human类的子类需要被代理时,需要新增一个新的代理类

由此引出动态代理

三、动态代理

使用动态代理时,我们不需要编写实现类,而是通过JDK提供的 Proxy.newProxyInstance() 创建一个Human接口的对象。

生成动态代理有以下几个步骤:

  • 定义一个 InvocationHandler 实例,它负责实现接口的方法调用;
  • 通过 Proxy.newProxyInstance() 创建interface实例,它需要3个参数:
    • 使用的 ClassLoader ,通常是接口类的 ClassLoader ;
    • 需要实现的接口数组,至少需要传入一个接口进去;
    • 用来处理接口方法调用的 InvocationHandler 实例。
  • 将返回的 Object 强制转型为接口。
interface Human{
    public void say();
}

class Student implements Human{

    @Override
    public void say() {
        System.out.println("I'm a Student");
    }
    
    @Override
    public void eat() {
        System.out.println("I eat something");
    }
}

class MyInvocationHandler implements InvocationHandler {
    private Object object;

    public MyInvocationHandler(){}

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Begin");
        Object invoke = method.invoke(object, args);
        System.out.println("End");
        return invoke;
    }
}

public class ProxyTest {
    public static void main(String[] args) {
        MyInvocationHandler handler = new MyInvocationHandler(new Student());
        Human human = (Human) Proxy.newProxyInstance(
                Human.class.getClassLoader(),
                new Class[] {Human.class},
                handler);
        human.say();
        human.eat();
    }
}

当Human接口的实例中方法增加时,如新增eat()方法时,只需要在Student类中直接实例化该方法即可。

当有其他不属于Human类的子类需要被代理时,只需要将传入 MyInvocationHandler() 中的new Student()替换为需要被代理的子类即可。

综上所述,通过动态代理基本可以解决静态代理的痛点。

四、Mybatis中的动态代理

在Springboot项目中配置Mybatis时,我们仅编写了Mapper接口,并未编写Mapper接口的实现类,那么当我们调用Mapper接口中方法时,是如何生成方法体的呢?

首先,项目在启动时生成MapperFactoryBean对象,通过 factory.getObject() 方法获取mapper的代理对象

将上述过程与动态代理的步骤进行对比,我们最终获取的是一个类似于动态代理例子中Human的代理对象,这里是MapperProxy的代理对象。至此,一个Mapper代理对象就生成完毕。

然后,当我们完成项目中Mybatis的相关配置后,使用我们Mapper接口中的数据库相关方法时,将调用之前生成的MapperProxy代理对象中 invoke() 方法。类比动态代理的例子,即调用MyInvocationHandler类中的 invoke() 方法。

//83行代码含义:如果method为Object中定义的方法(toString()、hash()...)则直接执行,这里我们要执行的是Mapper接口中定义的方法,显然返回为false
Object.class.equals(method.getDeclaringClass())

于是执行 cachedInvoker(method) 的 invoke() 方法

进入 execute() 方法,我们看到之前我们配置的mapper.xml在MapperMethod初始化时,被解析成了59行的command。在此处通过sqlSession对象实现了对数据库的操作。

至此,我们对Mybatis的数据库操作流程已经有了大致了解。回到开头的问题:为什么仅编写了Mapper接口,并未编写Mapper接口的实现类,仍然可以实现我们的功能?这与我们之前的动态代理例子有什么区别呢?

研究代码我们发现,我们并没有直接使用 method.invoke() 方法来调用实现类中的方法,而是调用了 cachedInvoker(method) 的 invoke() 方法解析我们配置的Mapper.xml,并通过sqlSession实现了数据库操作,这个 invoke() 方法相当于Mybatis自定义的方法。因此,这里的 invoke() 方法具体执行的逻辑是根据Mapper.xml配置来生成的,这个Mapper.xml配置可以理解为Mapper接口的实现类。

Qwen3-VL、Qwen3-Next与Qwen3.5多模态架构深度解剖 多模态大模型的核心不在参数规模,而在于视觉与文本如何协同建模。本文从基础概念切入,解析视觉语言模型中视觉编码器、跨模态注意力、特征对齐与token压缩等关键原理;阐述ViT、CLIP-ViT及动态压缩模块(HDTC)在语义表征、空间感知与计算效率上的技术权衡;强调结构设计如何决定模型在医学影像、工业质检、遥感分析等高要求场景中的真实能力边界;最终聚焦通义千问最新三套VL架构——Qwen3-VL、Qwen3-Next与Qwen3.5——揭示其背后迥异的融合哲学与工程取舍,为选型、微调与推理优化提供底层依据。 阅读详情

相关推荐

新手避坑指南:用SARScape 5.6.2处理Sentinel-1数据做SBAS-InSAR,这些参数设置错了白忙活

本文详细介绍了使用SARScape 5.6.2处理Sentinel-1数据做SBAS-InSAR时的关键参数设置技巧,帮助新手避免常见错误。重点解析了连接图生成、干涉工作流、DEM处理等环节的12个关键参数,包括Max Normal Baseline、Unwrapping Coherence Threshold等,提供实测安全值范围和优化建议,确保处理效率和结果准确性。

weixin_30694389的博客 559

静态代理和动态代理

代理模式是一种结构型设计模式,它为目标对象提供一种代理,用来控制对目标对象的访问。代理对象在客户端和目标对象之间起到中介的作用。客户端通过代理对象间接地访问目标对象,而不需要直接与目标对象进行交互。可以在不改变目标对象内容的前提下,通过代理对象扩展目标对象的行为逻辑;根据代理创建的时期静态代理:以硬编码的方式,手动定义创建的代理类;动态代理:代理类是在运行时动态创建的,在DK的核心类库中,可以使用 Java.lang.reflect.Proxy 类和接来生成动态代理;代理模式的应用场景。

weixin_71072718的博客 2641

HEVC/VVC中R-Lambda码率控制算法原理

文章目录1. 比特分配1.1 GOP级比特分配1.2 帧级比特分配1.3 LCU级比特分配2. 码率控制2.1 λ的计算和更新2.2 参数QP的确定 VVC中码率控制算法沿用了HEVC中经典的R-λ码率控制模型,R-λ由中科大的李斌博士提出(详情参考JCTVC-K0103)。R-λ模型的基础为视频编码中 R(比特 bpp)和 D(失真 MSE)之间的双曲线模型,即 D(R)=CR−KD(R) = ...

Aidoneus_y 6138

Mybatis——代理模式

代理模式是一种结构型设计模式,它的概念很简单,它通过创建一个代理对象来控制对原始对象的访问。代理模式主要涉及两个角色:代理角色和真实角色。代理类负责代理真实类,为真实类提供控制访问的功能,真实类则完成具体的业务逻辑。这样,当我们不方便或者不能直接访问真实对象时,可以通过代理对象来间接访问。使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。

nine06的博客 1710

Tesseral 建立地震模型

0. 前言 本节内容主要是总结如何使用 Tesseral 工具建立模型。 1. 模型建立步骤 设置模型的宽度和深度 此处默认都为1000,之后点击“确定” 建立地层 绘制新的地层 右键点击“New polygon” 绘制地层,设置第二个层的名字和纵波速度 绘制第三层,第三层覆盖在前一个层上 第四层如上,第四层如果是最后一层,绘制该层时,要将深度1000包围。 设置观测系统 设置炮点 设置子波为雷克子波,频率设置为30 检波点设置 运行模型 设置好如上选择后,

weixin_41857483的博客 6540

华为交换机与思科/华三设备LACP对接实战:手把手教你配置链路聚合

本文详细解析了华为交换机与思科、华三设备间的LACP链路聚合配置实战,涵盖核心原理、配置步骤及排错技巧。通过对比不同厂商的实现差异,提供可落地的跨厂商对接方案,助力企业网络工程师高效部署高可靠性链路聚合。

weixin_30836759的博客 426

MyBatis详解、静态代理与动态代理

MyBatis详解、静态代理与动态代理。

秦矜のblog 2021

告别死记硬背!用实际案例带你玩转UE5编辑器界面(附场景搭建练习)

本文通过实际案例教学,带你轻松掌握Unreal Engine5编辑器界面的核心功能。从创建基础场景到添加光源和可交互对象,逐步讲解内容浏览器、模式面板、世界大纲等模块的协同工作方式,告别死记硬背的学习模式。附场景搭建练习,助你快速上手UE5开发。

weixin_30566063的博客 731

Mybatis—代理模式

代理模式是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理类通常在原始对象的基础上提供了一些额外的功能,例如远程访问、安全性控制、延迟加载等。通过使用代理模式,可以在不改变原始对象的情况下增加一些额外的功能,同时也可以对原始对象进行保护和封装。

qwLily的博客 692

【入门篇】第五章 第一次与 AI Agent 交互

本文介绍了OpenClaw中最基本的用户与AI Agent交互方式,剖析了Agent和Gateway两个核心组件的作用,通过简单示例展示了从用户请求到结果返回的完整执行流程,说明了最小交互过程对验证系统可用性的重要意义,为后续学习复杂任务执行机制奠定基础。

lanyv的博客 512

推荐一个直接用于项目开发的PID库!很好用,很稳定

关注、星标公众号,不错过精彩内容大家好,我是小麦。最近有朋友问到有没有现成的C语言PID库。当然有了!现在我就准备给大家安利一下了。一般同学会去某度上搜,看到各种各样版本的PID示例,或者...

一名热爱技术的工程师的博客。分享技术干货,记录美好生活。永远相信美好的事情即将发生。 9028

JDK动态代理

动态代理(理解) 这笔记能让你把动态代理掌握到什么程度呢? 1.什么是动态代理? 2.动态代理能做什么? 3.mybatis spring 框架中提到动态代理 你不会懵逼; 第一章:代理的介绍 1.什么是代理 代理 无处不在; 中介,商家,代购等等; 比如有一个美国大学,面向全世界招生, 留学中介(代理); 留学中介(代理):帮助这家美国学校招生,中介就是学校的代理,中介代替学校招生; 这个 中介就是代理 代理的特点 1.中介和代理他们要做的事情是一致的:招生; 2.中介是学校的代理,学校是目标 3.家长-

weixin_45231660的博客 1357

Google Gemini 模型本地可视化

Google近期发布了Gemini模型,而且开放了Gemini Pro API,Gemini Pro 可免费使用!Gemini Pro支持全球180个国家的38种语言,目前接受文本、图片作为输入并生成文本作为输出。Gemini Pro的表现超越了其他同类模型,当前版本配备了 32K 文本上下文窗口,可免费使用,且其定价将十分有竞争力。Gemini Pro具备丰富的功能:函数调用、数据嵌入、语义检索、自定义知识嵌入以及聊天功能。

HJ_blog 1250

【SSM框架解析】——前篇:详解动态代理【案例驱动】(案例源码自取)

通过实例驱动详解 动态代理 ,贴近生活。源码自取,下一篇就将进入 Mybatis框架学习,本专栏将持续更新知道SSM框架全部学完,最中将共同完成一个入门企业级项目。

muzi_longren的博客 1318

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Java动态代理模式的奥秘

wanghao112956的博客 388

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

深入理解 Java 代理:从静态代理到动态代理的完整指南

代理模式(Proxy Pattern)是 Java 中一种重要的设计模式,它通过创建一个代理对象来控制对原始对象的访问。代理对象在客户端和目标对象之间起到中介作用,可以在不修改目标对象代码的情况下,增加额外的功能或控制访问。代理模式的核心价值访问控制:控制客户端对真实对象的访问权限功能增强:在不修改原对象代码的情况下添加新功能延迟加载:只有在真正需要时才创建或加载目标对象简化客户端:客户端只需与代理对象交互,无需了解复杂的实现细节。

yexianglunbai的博客 206

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

mysql动态代理_动态代理及应用深度解析

课程目的:通过本课程学习,让你一次性解决面试常问、无处不在的Java代理模式,提升自己的技术功底。适用人群:具有一定Java基础的开发人员。课程概述:设计模式(Design Pattern)是一套被反复使用、凝结着前人智慧与经验的代码设计总结,而代理模式就是其中一种无处不在的设计模式。代理模式指的是当我们程序中的某一段代码不方便进行改造,或者不方便加入其它内容的时候,我们可以加入代理类的设计去实现...

weixin_42365688的博客 199

Mybatis-Spring源码分析(三):SqlSessionTemplate基于动态代理实现线程安全

概述 在mybatis中定义了SqlSession接口用于封装一个数据库的连接,通过该数据库连接来对数据库发起相关数据库操作请求并获取结果集。SqlSession接口在mybatis中的默认实现为DefaultSqlSession,其中DefaultSqlSession不是线程安全的,即多个需要访问数据库的线程不能共享同一个DefaultSqlSession的对象实例,否则会出现线程之间的数据...

源码之下,了无秘密 4602

Java的代理模式

代理模式是Java开发中重要的结构型设计模式,代理模式分为静态代理和动态代理(JDK动态代理、CGLib动态代理)。本文详细介绍了三种实现方式的原理、代码示例及适用场景,帮助开发者根据需求选择合适的代理方案。

2401_84284464的博客 1074

设计模式之代理模式

本文由老王出租房子引出——代理设计模式,将从最简单的静态代理实现开始,后延伸使用jdk实现动态代理,最后扩展到Cglib实现动态代理。为了更深入理解代理模式,我们会对实际应用中的典型案例进行介绍,包括在Spring和Mybatis中的应用。...

程序员田同学的博客 172

面试官:MyBatis你只写了接口为啥就能执行SQL啊?

点击上方“Java之间”,选择“置顶或者星标”你关注的就是我关心的!来源:Java识堂静态代理又是一年毕业季,很多小伙伴开始去大城市打拼。来大城市第一件事就是租房,免不了...

Java之间 568

从青铜到王者:Java设计模式——代理模式

代理模式是一种结构型设计模式,通过代理对象控制对目标对象的访问。静态代理在编译期确定代理类,需要定义接口、实现类和代理类。代理对象可添加权限检查、日志记录等功能,实现访问控制、功能增强、解耦和延迟加载等作用。类似生活中的房产中介、明星经纪人等,代理模式在软件开发中广泛应用于安全控制、性能监控等场景。

m0_73590302的博客 1410

【自用】mybatis openSession源码流程

救命啊,我实在啃不动了,太他吗痛苦了 configuration对象概念 openSession 点这个,可以看到这个接口的实现方法 调构造,返回了什么寄吧东西 好像是一个实现类对象 executor 是一个事务对象 点这个 看看里面的属性 断点太多了,怎么办,取消断点 这么取消断点 getMapper 进入方法 又掉了configuration里面的getMapper方法 我不行了,我不记录了,就这样吧 又调了mapper注册器里面的getMapper方法 终于不调了,主要看这

qq_42765493的博客 321

Java代理模式详解:静态代理、JDK动态代理与CGLIB实战

在复杂业务系统中,横切逻辑与业务代码的耦合常导致维护成本飙升。面向切面编程(AOP)通过代理机制将日志、事务、权限等通用关注点动态织入目标对象,实现无侵入增强。Java代理模式是理解AOP的基石,核心分为静态代理与动态代理:静态代理在编译期手工编写代理类,结构清晰但易产生类爆炸;动态代理在运行时生成代理类,JDK动态代理基于接口代理,CGLIB则通过子类继承实现代理。二者在原理、限制及性能上差异显著,而这正是Spring AOP底层选择JDK动态代理或CGLIB的依据。从Spring事务管理到MyBatis

weixin_33585822的博客 242

代理模式

文章目录代理模式案例模式介绍代码改造模式应用总结参考资料 代理模式 案例 张三在北京上班,最近有事要回老家上海。于是他想着去火车站买票,接下来就简单的模拟这一过程。 1.创建火车站的类: /** * 模拟火车站,提供购票的方法 */ public class TrainStation { public String buy(String start, String end) { return "车票:[起点:" + start + "\t终点:" + end + "]";

Phoegel的博客 191

Java设计模式_代理模式详解

代理模式(Proxy Pattern)为其他对象提供一种代理,以控制对这个对象的访问。简单来说,就是"通过代理者来访问目标对象",代理者可以在访问前后做额外的事情(如权限检查、日志记录、延迟加载等),而不需要修改目标对象本身的代码。📌一句话理解:你找明星代言产品,你接触的"代言"是代理(Proxy),真正拍广告的是明星(RealSubject)。静态代理:编译时确定,简单但不够灵活JDK 动态代理:运行时生成,基于接口,Spring AOP 默认选择CGLIB 动态代理。

Zhou141136的博客 284
上一篇: 架构师必备技能:教你画出一张合格的技术架构图
下一篇: Mybatis架构原理--二级缓存源码剖析
JavaShark
博客等级 码龄4年 184粉丝 438原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值