代理和动态代理

JDK动态代理和CGLIB动态代理 在SpringAOP中基于动态代理实现功能的增强,也就是动态的生成代理类,在代理类中织入增强的逻辑然后调用目标对象的方法。动态代理中用的比较多的两种:JDK动态代理、CGLIB动态代理。 JDK动态代理 使用JDK的java.lang.reflect.Proxy类的newProxyInstance方法实现的代理。 用一个测试接口看下具体实现: public interface JdkProxyDemoService { void queryTrs(); } @Service public 阅读详情

静态代理

代理-顾名思义就是自己不想做或者不方便的做的事情交给别人来做,自己就是被代理对象,被人就是代理对象。从实现上来说其实很简单-就是代理对象持有被代理对象的引用,调用的时候使用代理对象而不是被代理对象。这样做的目的通常是可以通过代理对象在执行时候可以在相应的方法上加上附加的功能。
来看一段代码:

//定义接口-被代理对象接口
public abstract class Person {
    public abstract void marry();
}
//某一个被代理对象
public class DaiSi extends Person {
    public void marry() {
        System.out.printf("find a ugly girl \n");
    }
}
//代理类
public class MatchMaker {
    //持有被代理对象
    private Person person;
    public MatchMaker(Person person) {
        this.person = person;
    }
    public void marry(){
        //添加附加功能
        System.out.println("find a girl..."); //前置执行代码
        person.marry();
        System.out.println("hei hei hei "); //后置执行代码

    }

}
//测试类
public class Main {
    public static void main(String[] args) {
        MatchMaker matchMaker = new MatchMaker(new DaiSi());
        //使用代理对象
        matchMaker.marry();
    }
}
输出:
find a girl...
find a ugly girl 
hei hei hei 

静态代理就到此为止,接下来重点说说jdk的动态代理

JDK动态代理

我们还是以上面的为例子:

//JDK动态代理需要定义接口
public interface Person {
    public void marry();

}
//某一个Person还是保持不变
public class Daisi implements Person{
    public void marry() {
        System.out.println("love ugly girl!");
    }
}
//JSK动态代理需要实现InvocationHandler接口
public class MatchMaker implements InvocationHandler {
    //持有一个Object对象
    private Object sub;
    public MatchMaker() {
    }

    public MatchMaker(Object sub) {
        //初始化Object
        this.sub = sub;
    }
    //这个是自定义的方法,可有可无 只是用于更加方便的获取对象
    public Object getInstance(){
        //可以看出 jdk自带的动态代理是需要实现接口的
        return Proxy.newProxyInstance(sub.getClass().getClassLoader(),sub.getClass().getInterfaces(),this);
    }


    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before calling + "+method.getName());
        method.invoke(sub,args);
        System.out.println( "after calling "  + method.getName());
        return null;
    }
}
public class Main {
    public static void main(String[] args) throws Exception{
        Daisi ds = new Daisi();
        MatchMaker matchMaker = new MatchMaker(ds);
        Person person = (Person) matchMaker.getInstance();
        System.out.println(person.getClass());//class com.sun.proxy.$Proxy0
        person.marry();//实际上调用的是InvocationHandler 的方法
        /**
         * 动态代理的执行分为5个阶段:
         * 1.拿到代理的对象 并获取他的接口:sub.getClass().getInterfaces()
         * 2.JDK代理重新生成一个类,同时实现我们给代理对象的接口 class com.sun.proxy.$Proxy0
         * 3.拿到代理对象的引用 //$Proxy0会持有 DaiDi类的引用
         * 4.重新动态生成一个class的字节码
         * 5.编译
         */
        //下面的代码 可以用来将 com.sun.proxy.$Proxy0 生成class文件
        byte[] data = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Person.class});
        FileOutputStream os = new FileOutputStream("E:/$Proxy0.class");
        os.write(data);
        os.close();
    }
}

我们在来看看 $Proxy0.class 反编译 文件来印证我们上面说的过程:

//反编译的类实现了 Person 所以会有marry()方法
public final class $Proxy0 extends Proxy implements Person {
    //这个m1 , m2 , m3 , m0是根据方法的个数生成的
    private static Method m1;
    private static Method m2;
    private static Method m0;
    private static Method m3;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }
    //这个就是 marry方法 
    public final void marry() throws  {
        try {
            //这里的super.h其实就是: protected InvocationHandler h;而这个变量 我们在$Proxy0的构造里面进行了初始化,所以可以看到 在这里实际上就是调用了InvocationHandler里面的invoke方法
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
            m3 = Class.forName("com.designModel.agentAndDynamicAgent.dynamicAgent.Person").getMethod("marry", new Class[0]);
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

总结:
JDK动态代理实现:
1.创建一个代理类实现InvocationHandler
2.持有被代理对象,或者直接用Object
3.对代理对象初始化,可以选择在构造中初始化,也可以选择其他方式
4.实现invoke方法
5.调用的时候 使用Proxy.newProxyInstance()获取对象,这个就是我们使用的代理对象

 public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

静态代理和动态代理的区别

静态代理在程序运行前就已经生成了代理类对象,而动态代理是在程序在运行是才生成的,然后通过类加载器将字节码加载到JVM中.

jdk动态代理和cglib动态代理对比 JDK 动态代理:只代理接口(interface),无法代理类。它使用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现动态代理。 CGLIB 动态代理:可以代理类和接口。它通过生成目标类的子类来创建代理对象,因此可以代理没有实现接口的类。 阅读详情

相关推荐

学习Python,小白如何搭建Python环境?

学习Python,首先需要搭建好Python环境,主要分为【运行环境搭建】、【开发环境搭建】以及【Python环境配置】三个环节,接下来我将对Python环境搭建这三个部分进行介绍。

weixin_72923265的博客 9005

秒懂Java代理与动态代理模式

版权申明】非商业目的可自由转载 博文地址: 出自:shusheng007 概述 什么是代理模式?解决什么问题(即为什么需要)?什么是静态代理?什么是动态代理模式?二者什么关系?具体如何实现?什么原理?如何改进?这即为我们学习一项新知识的正确打开方式,我们接下来会以此展开,让你秒懂。 概念 什么是代理模式 定义:为其他对象提供一种代理以控制对这个对象的访问 ...

ShuSheng007的程序人生 2万+

EB配置输入捕获ICU模块----基于S32K3

基于S32K311芯片,EB配置ICU输入捕获(Emios 和Siul)

weixin_43586400的博客 1772

Java中动态代理的两种方式JDK动态代理和cglib动态代理以及区别

上篇介绍了一下静态代理:Java中的代理模式——静态代理以及分析静态代理的缺点 也分析了一下静态代理的缺点: 1、由于静态代理中的代理类是针对某一个类去做代理的,那么假设一个系统中有100个Service,则需要创建100个代理类 2、如果一个Service中有很多方法需要事务(增强动作),发现代理对象的方法中还是有很多重复的代码 3、由第一点和第二点可以得出:静态代理的重用性不强 那怎...

曹举的个人博客 2万+

从零开始VCS+Verdi 安装过程

从零开始VCS+Verdi 安装及破解过程 主要参考:VCS+Verdi 安装及破解过程(CentOS7)-----FPGA开发 1. 安装文件结构 –vcs-mx_vL-2016.06 –verdi_vL-2016.06-1 –scl_v11.9 #此程序统一管理license等破解文件 –SynopsysInstaller.rar #此程序用于安装以上3个程序 –sc...

Ztrans的博客 2万+

目标检测数据集 第069期-基于yolo标注格式的玻璃清洁状态检测数据集(含免费分享)

但这类技术的落地,离不开大量标注规范、场景丰富的数据集作为算法训练的支撑,玻璃清洁状态检测数据集的出现,正是为了满足这一市场与技术需求。在高校与科研机构的计算机视觉研究中,该数据集可作为基础研究素材,用于探索物体状态识别的算法优化方向,比如针对玻璃这类透明物体的检测算法改进,或是小样本场景下的状态识别研究。通过摄像头采集车窗、挡风玻璃的图像,算法自动检测玻璃清洁度,若识别到脏污影响视线,及时提醒运维人员清洁,避免因玻璃脏污引发的安全事故,提升交通出行的安全性。

深度学习算法工程师,专注于前沿算法研究与实战应用。在这里,我将分享深度学习领域的实战经验、优质数据集资源以及最新论文解读与精度分析,旨在与广大技术爱好者共同探索人工智能的奥秘,助力技术成长与创新。 128

JDK动态代理和CGLIB动态代理有什么区别?

JDK动态代理和CGLIB动态代理有什么区别?

水w的博客 8019

OpenClaw更新后变傻了?一分钟教你快速恢复(OpenClaw更新版本后降智、缺少权限问题的解决方案)

OpenClaw 版本更新后出现降智问题,AI不再执行具体任务。本文详细分析问题原因,提供最简便的解决方案✅

XiaoqiangClub的博客 3884

java动态代理:jdk动态代理和cglib动态代理

java动态代理

记录学习点滴 3317

解锁Vscode:C/C++环境配置超详细指南

本文详细介绍如何在 VSCode 中配置 C/C++ 开发环境,帮助开发者快速搭建高效的编码调试环境。内容涵盖前期准备、软件下载安装、环境变量配置、工作区文件设置及测试运行全流程:首先需准备 VSCode 编辑器、MinGW-w64 编译器及 C/C++ 插件;接着完成工具下载与安装,配置系统环境变量以确保编译器可全局调用;然后通过创建.vscode工作区文件夹,配置核心文件,实现代码智能提示与调试功能;最后通过编写 Hello World 示例验证环境可用性,并附上常见问题排查方案。

邓邓子的博客 3047

如何在飞腾平台上安装Ubuntu操作系统

注意: 若主板上配置的是NVME硬盘,在进行内核配置时,需要将内核的NEME驱动勾选上,否则移植内核时,无法找到文件系统,进不去操作系统。可以通过rufus软件将镜像做到U盘中,本次使用版本为Rufus 3.9.124 ,其他版本也可以。不要下载live版本的,没有准备网络环境,是一个头疼的事情,笔者暂时没有实现网络安装。将U盘接到主板usb口上,接上串口,显示器,,必需串口有打印才可以安装。可以通过dd命令,将iso安装到U盘。安装的是最小系统,缺少很多命令,需要联网更新,或则更换飞腾专用内核。

技术联盟 2645

【动态代理】—— JDK和cglib的动态代理

概述 设计模式中有一个代理模式,它为其他对象提供一种代理以控制对这个对象的访问。 关于代理模式可以参考:【每天一个java设计模式(七)】 - 代理模式:https://blog.youkuaiyun.com/weixin_43598687/article/details/122072282 代理模式是指的静态代理。使用静态代理很容易就完成了对一个类的代理操作。但是静态代理的缺点也暴露了出来:由于代理只能为一个类服务,如果需要代理的类很多,那么就需要编写大量的代理类,比较繁琐。 而动态代理可以在程序运行期间,在不修改源

1+1=王的博客 4464

一个人干完整个运营团队!浙大开源「Easel」全链路拆解:从热点发现到自动发布,一个 Agent 直接做出来

一个人干完整个运营团队?浙大 REAL 实验室开源的 Easel,把 OpenClaw Agent、账号画像、114 个内容技能和真实媒体工具接在一起:从热点发现、选题策划、图文视频创作,到七平台适配发布、数据归因复盘,全链路一个 Agent 闭环完成,产物按项目归档。本文完整拆解其五层工作流、四层 Prompt Stack 架构、画像内联机制、Skill 三层加载与产物契约,附安装部署、.env 关键配置、Embedding 避坑、已知问题修复等实战干货,全程无虚构、可复现。

program哲学 295

静态代理和动态代理

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

weixin_71072718的博客 2640

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

动态代理和静态代理的区别_静态代理和动态代理

一:什么是代理模式1.定义:为其他对象提供一种代理以控制对这个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。2.例子:最开始接触JDBC操作数据库的时候,业务层每一个方法都需要做以下几件事(1)打开数据库连接(2)执行我们想要的操作(3)关闭数据库连接此时,我的核心业务是第(2)步,其余两步为辅助业务。当核心业务与辅助业务写在了一个方法中时。会...

weixin_39941732的博客 5717

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

浅谈java代理 静态代理动态代理 JDK动态代理和CGLIB动态代理

浅谈java代理 静态代理动态代理 JDK动态代理和CGLIB动态代理

园区阿祖的博客 1313

实例理解JDK动态代理和Cglib动态代理及其区别

实例理解JDK动态代理和Cglib动态代理及其区别 深入理解设计模式之代理模式 代理商代理化妆品生产理解JDK动态代理 代理商代理汽车制造理解Cglib动态代理

Duktig的博客 6064

JDK 动态代理和 CGLIB 动态代理

JDK 动态代理和 CGLIB 动态代理静态代理JDK 动态代理CGLIB 动态代理总结 我们在阅读一些 Java 框架的源码时,基本上常会看到使用动态代理机制,它可以无感的对既有代码进行方法的增强,使得代码拥有更好的拓展性。 通过从静态代理、JDK 动态代理、CGLIB 动态代理来进行本文的分析。 静态代理 静态代理就是在程序运行之前,代理类字节码.class就已编译好,通常一个静态代理类也只代...

@龙猫的博客 3711

什么是动态代理?动态代理和静态代理的区别

静态代理适合简单场景,但代码冗余。动态代理通过反射或字节码技术动态生成代理类,灵活且高效。JDK 动态代理基于接口,CGLIB基于继承,根据需求选择合适方式。

lonelykkk的博客 1253

静态代理VS动态代理(JDK动态代理和CGLIB动态代理)

代理模式是一种比较好理解的设计模式。简单来说就是。代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作。:新娘找来了自己的姨妈来代替自己处理新郎的提问,新娘收到的提问都是经过姨妈处理过滤之后的。姨妈在这里就可以看作是代理你的代理对象,代理的行为(方法)是接收和回复新郎的提问。1.定义发送短信的接口2.实现发送短信的接口。

weixin_61819532的博客 973

java动态代理和cglib动态代理

Java 动态代理和Cglib动态代理

leon709的专栏 1万+

spring的动态代理和静态代理

代理是一种设计模式,提供了对目标对象另外的访问方式,即通过代理对象访问目标对象。可以不修改目标对象,对目标对象功能进行拓展。在我们学习Spring的时候就会发现,AOP(面向切面编程)的底层就是代理。代理的实现可以分为静态代理和动态代理。动态代理又根据实现的方式分为:基于JDK接口的动态实现和基于Cglib类的动态实现。

MuXinMeng的博客 1863

jdk动态代理和cglb动态代理

动态代理和静态代理都是代理模式的实现方式,其主要区别在于代理类生成的时机和方式。静态代理是在编译时就确定了代理类的代码,在程序运行前就已经存在了代理类的class文件。代理类与委托类的关系在编译时就已经确定,因此被称为静态代理。在静态代理中,代理类需要实现与委托类相同的接口或者继承委托类的父类,以便能够对委托类进行代理操作。动态代理是在程序运行时生成代理类的代码,代理类通过反射机制动态生成。动态代理不需要像静态代理一样实现与委托类相同的接口或继承委托类的父类,它可以实现任意接口。

一个菜鸡的博客 1070

Spring中两种动态代理:JDK动态代理和CGLib动态代理

基本概念 自Java 1.3以后,Java提供了动态代理技术,允许开发者在运行期创建接口的代理实例,后来这项技术被用到了Spring的很多地方。 JDK动态代理主要涉及java.lang.reflect包下边的两个类:Proxy和InvocationHandler。其中,InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态地将横...

程铭程铭你快成名的博客 1966
上一篇: 线程同步工具-CyclicBarrier
下一篇: 使用CGLIB实现动态代理
最伤离别
博客等级 码龄15年 15粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值