动态代理JDK于cglib

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

静态代理的缺点:

1、由于静态代理中的代理类是针对某一个类去做代理的,那么假设一个系统中有100个Service,则需要创建100个代理类
2、如果一个Service中有很多方法需要事务(增强动作),发现代理对象的方法中还是有很多重复的代码
3、由第一点和第二点可以得出:静态代理的重用性不强
那怎么解决呢?
用动态代理就可以很好的解决上述问题,本篇介绍一下:Java中的动态代理
动态代理实现的目的和静态代理一样,都是对目标方法进行增强,而且让增强的动作和目标动作分开,达到解耦的目的
动态代理分为JDK的动态代理和cglib动态代理,他俩有略微的差别:cglib动态代理产生的代理对象是目标对象的子类。
下面分别介绍JDK的动态代理(是JDK的代码实现的)和cglib动态代理(是cglib的jar包实现的)

JDK的动态代理

Interface
package com.itheima.proxy;

/**
 * 对生产常见的要求
 */
public interface IProducer {
    /**
     * 销售
     * @param money
     */
    public void saleProduct(float money);

    /**
     * 售后
     * @param money
     */
    public void afterServer(float money);
}

Producer
package com.itheima.proxy;

/**
 * 一个生产者[需要符合代理商的要求,代理商的要求是 要有销售和售后]
 */
public class Producer implements IProducer {
    /**
     * 销售
     *
     * @param money
     */
    public void saleProduct(float money) {
        System.out.println("拿到钱,卖出产品"+money);
    }

    /**
     * 售后
     *
     * @param money
     */

    public void afterServer(float money) {
        System.out.println("提供售后服务,并拿到钱"+money);
    }
}

client
package com.itheima.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 模拟一个消费者
 */
public class client {
    public static void main(String[] args) {
        //生产者
        final Producer producer = new Producer();
        /**
         * 动态代理
         * 特点:字节码 随用随创建,随用随加载
         * 作用:不修改源码的基础上对方法增强
         * 分类:基于接口的动态代理
         *          设计的类 peoxy
         *          提供者:JDK官方
         *
         *      基于子类的动态代理
         *如何创建代理对象
         *      使用Proxy类中的newProxyInstance方法
         *创建代理对象的要求
         *      被代理类必须实现一个接口,如果没有则不能使用
         * newProxyInstance 参数
         *        ClassLoader:类加载器
         *          它是用于加载代理对象的字节码的,和被代理对象使用相同的类加载器 固定写法
         *        class[]:字节码数组
         *          它是用于让代理对象和被代理对象有相同的方法。 固定写法
         *        InvocationHandler :用于提供增强的代码
         *          它是让我们写如何代理,我们一般都是写一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的
         *          此接口的实现类都是谁用谁写
         *
         */
        /*代理对象为  iProducer。被代理对象producer*/
        IProducer iProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(), new InvocationHandler() {
            /**
             *  作用:执行被代理对象的任何接口方法都会经过该方法
             * @param proxy  代理对象的引用
             * @param method 当前执行的方法
             * @param args   当前执行方法的参数
             * @return       和被代理对象方法有相同的返回值
             * @throws Throwable
             */
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                提供增强的代码
                Object returnValue = null;
//                获取方法执行的参数
                Float money = (Float) args[0];
//                判断当前的方法是不是销售
                if ("saleProduct".equals(method.getName())) {
                    returnValue = method.invoke(producer, money * 0.8f);
                } else {
                    returnValue = method.invoke(producer, money * 0.08f);
                }
                return returnValue;
            }
        });
        iProducer.saleProduct(10000f);
        iProducer.afterServer(1000f);
    }
}

结果
拿到钱,卖出产品8000.0
提供售后服务,并拿到钱80.0

cglib动态代理

client
package com.itheima.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class client {
    public static void main(String[] args) {
        final Producer producer = new Producer();
        /*
        动态代理:
            特点:字节码随用随创建,随用随加载
            作用:在不修改源码的基础上对方法增强
            分类:
                基于接口的动态代理
                基于子类的动态代理
                    涉及的类:Enhancer
                    提供者:   第三方cglib库
                如何创建代理对象:
                    使用Enhance类中的create方法
                创建代理对象的要求:
                    被代理对象的类不能是最终类
                create方法的参数
                    class:字节码
                        它是用于指定被代理对象的字节码
                    CallBack:用于提供增强的代码
                        它是让我们写如何代理,我们一般都是写一个该接口的实现类,通常情况下采用匿名内部类,但是不是必须的
                        我们一般写的都是该接口的子接口的实现类,MethodInterceptor
        */
        Producer producerProxy = (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
            /**
             * 执行被代理对象的任何方法都会经过该方法, 具有拦截作用
             *
             * @param proxy
             * @param method
             * @param args        以上是哪个参数和基于接口的动态代理中的invoke方法的参数是一样的
             * @param methodProxy 当前执行方法的代理对象
             * @return
             * @throws Throwable
             */
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object returnValue = null;
                Float money = (Float) args[0];
                if ("saleProduct".equals(method.getName())) {
                    returnValue = method.invoke(producer, money * 0.8f);
                }else {
                    returnValue = method.invoke(producer, money * 0.08f);
                }
                return returnValue;
            }
        });
        producerProxy.saleProduct(10000f);
        producerProxy.afterServer(1000f);

    }
}

Producer
package com.itheima.cglib;

public   class Producer {
    /**
     * 销售
     *
     * @param money
     */
    public void saleProduct(float money) {
        System.out.println("拿到钱,卖出产品"+money);
    }

    /**
     * 售后
     *
     * @param money
     */

    public void afterServer(float money) {
        System.out.println("提供售后服务,并拿到钱"+money);
    }
}

结果
拿到钱,卖出产品8000.0
提供售后服务,并拿到钱80.0

以上就是动态代理的两种实现。

我们用上边的做法去实现目标方法的增强,实现代码的解耦,是没有问题的,但是还是需要自己去生成代理对象,自己手写拦截器,在拦截器里自己手动的去把要增强的内容和目标方法结合起来,这用起来还是有点繁琐,有更好的解决方案吗?

答案是:有的!那就是Spring的AOP,这才是咱们最终想引出来的重点!

有了Spring的AOP后,就不用自己去写了,只需要在配置文件里进行配置,配置好后Spring按照你的配置去帮你生成代理对象,按照你的配置把增强的内容和目标方法结合起来。就相当于自己写代码也能实现和aop类似的功能,但是有了Spring aop以后有些事情Spring帮你做了,而且人家Spring做成了可配置化,用起来非常简单而且很灵活

咱们上边用的JDK动态代理和cglib动态代理,这两种在Spring的AOP里都有用到,Spring是根据不同的情况去决定是使用JDK的动态代理生成代理对象,还是使用cglib去生成代理对象。

JDK和CGLIB动态代理区别 前言 JDK动态代理实现原理(jdk8):https://blog.youkuaiyun.com/yhl_jxy/article/details/80586785 CGLIB动态代理实现原理:https://blog.youkuaiyun.com/yhl_jxy/article/details/80633194 一 JDK和CGLIB动态代理原理 1、JDK动态代理 利用拦截器(拦截器必须实现I... 阅读详情

相关推荐

jdk动态代理和cglib动态代理对比

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

zfj321的博客 1544

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

java动态代理

记录学习点滴 3318

【JVM与性能调优】JVM动态代理、JDK动态代理和CGLib动态代理傻傻分不清楚

JDK动态代理和CGLib动态代理都是Java中用于创建动态代理的方法,但它们的实现方式不同。

奶爸的编程之路,也就一周冷个三天 1656

动态代理模式之cglib和JDK动态代理

一文讲清楚动态代理模式

搬运工007 953

代理设计模式:静态代理和动态代理的理解、实现与区别(优缺点)与SpringAOP的3种配置方式案例工程代码

此资源为文章中《代理设计模式:静态代理和动态代理的理解、实现与区别(优缺点)》与《 AOP动态代理声明式的3种配置方式过程与区别》的案例代码,可下载参考学习。

静态代理和动态代理简单实现代码

静态代理和动态代理简单实现代码.Proxy.其中静态代理我写了两个demo,有一个是最原始的,还有一个放在程杰的大化设计模式的代理模式写的,纯属娱乐。

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

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

1+1=王的博客 4464

Java静态代理和动态代理

NULL 博文链接:https://wmwork2010.iteye.com/blog/631978

动态代理(CGlib和jdk)

代理模式: 动态代理 jdk和cglib

RwTo的博客 5031

【黑马点评】项目知识点及面经整理

【黑马点评】项目知识点及面经整理

m0_52031708的博客 6606

Kafka 系列 —(17)Kafka 流式处理:Kafka Streams架构、使用场景、框架选择

本文介绍了KafkaStreams的架构特点、应用场景及与其他流处理框架的比较。KafkaStreams作为嵌入式分布式流处理库,其核心架构包含流处理器、任务、拓扑和本地状态存储,具备自动容错和伸缩能力。适用于实时监控、ETL、聚合、Join、物化视图等低延迟场景。与Flink、Spark相比,KafkaStreams适合简单架构和微服务,而Flink适合大规模处理,Spark更适合批处理。选择框架需根据具体场景需求,如微服务推荐KafkaStreams,大规模处理推荐Flink。

moton2017的博客 1631

JDK动态代理、Cglib动态代理及Spring AOP

Java中的JDK动态代理是一种通过反射机制生成代理对象的技术,使得我们能够在运行时动态地创建某个接口的代理类,而无需手动编写实现类。JDK动态代理通常用于横切关注点(如日志、事务管理、安全性等)在方法调用前后进行处理,而不需要修改目标类的源代码。

意疏的博客 6385

HIDL概述

HIDL背景 Treble 是 Google Android 团队的一项重大项目,意在 Android 操作系统框架在架构方面的一项重大改变,旨在让制造商以更低的成本更轻松、更快速地将设备更新到新版 Android 系统。Android 7.x 及更早版本中没有正式的供应商接口,因此设备制造商必须更新大量 Android 代码才能将设备更新到新版 Android 系统: 图1 Treble ...

u013357557的专栏 2万+

通俗易懂 快速理解 JDK动态代理 和 cglib动态代理

动态代理有两种: ① jdk动态代理,要求必须有接口,最终生成的代理类和目标类实现相同的接口,在com.sun.proxy包下,类名为$proxy+数字 (例如:$proxy6) ② cglib动态代理,最终生成的代理类会继承目标类,并且和目标类在相同的包下

weixin_43935152的博客 1万+

Rocky Linux 9 离线环境Docker部署实战:从依赖打包到服务启动

本文提供了一份详尽的Rocky Linux 9离线环境Docker部署实战指南。针对无法访问外网的生产或内网服务器,文章详细讲解了如何在联网跳板机上下载Docker二进制包及所有系统依赖RPM包,并完成打包。随后,手把手指导在离线服务器上进行依赖安装、二进制文件部署、systemd服务配置、SELinux与防火墙调优,最终实现Docker服务的成功启动与验证。

weixin_28363123的博客 142

手把手教你学SINULINK-- --Linear Transformer 模块

模块是 Simulink 中用于模拟理想变压器行为的重要工具。通过本文的详细介绍,希望你能更好地理解和使用模块。

MHD0815的博客 2615

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

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

水w的博客 8019

华为OD机试双机位C卷-分披萨 (Py/Java/C/C++/Js/Go)

华为OD机试(机考)双机位C卷 【分披萨】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为od机试 - 分披萨。

qq_45776114的博客 1397

JDK和CGLIB动态代理的区别

学习动态代理的区别

qq_59527118的博客 2万+

【ACP】2025-最新-疑难题解析- 练习二汇总

全球加速是优化公网访问的,负载均衡是分发流量的,公网 NAT 网关是处理公网 IP 的,高速通道是建私网连接但不直接提供固定私网地址功能。C 是客户端加密方式,D 是 ECS 云盘加密,都不属于 OSS 服务器端加密。某企业想使用云服务器 ECS + 负载均衡 SLB + 弹性伸缩 (Auto Scaling) 的架构搭建一个企业级门户网站,技术负责人对于负载均衡和弹性伸缩配合使用没有经验,于是将他理解的两种产品配合使用的一些技术细节列成了一个表单,并请作为架构师的您帮他做一下鉴别,以下哪些项是正确的?

jundao1997的专栏 297

【RT-DETR有效改进】轻量级网络ShuffleNetV2(附代码+修改教程)

从今天开始正式开始更新RT-DETR剑指论文专栏,本专栏的内容会迅速铺开,在短期呢大量更新,价格也会乘阶梯性上涨,所以想要和我一起学习RT-DETR改进,可以在前期直接关注,本文专栏旨在打造全网最好的RT-DETR专栏为想要发论文的家进行服务。RT-DETR剑指论文专栏,持续复现各种顶会内容——论文收割机RT-DETR​​。

Snu77的博客 1996

JDK动态代理和CGLIB动态代理的区别

目录`JDK` 动态代理`CGLIB` 动态代理 JDK 动态代理 自 JDK 1.3 以后,Java 提供了动态代理技术,允许开发者在运行期创建接口的代理实例,后来这项技术被用到了 Spring 的很多地方。JDK 动态代理主要涉及 java.lang.reflect 包下边的两个类:Proxy 和 InvocationHandler。其中,InvocationHandler 是一个接口,可以通过实现该接口定义横切逻辑(如:我们在方法执行前后打印的日志,本文只是为了演示,实际的应用一般不会只是简单的打印日

桐花思雨 7084

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

JDK动态代理和CGLIB动态代理案例分析

JDK动态代理和CGLIB动态代理案例分析

我从不打没有准备的仗! 9991

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Cglib和jdk动态代理的区别

Cglib和jdk动态代理的区别? a) Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理 b) Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理 c) 什么时候用cglib什么时候用jdk动态代理 i. 目标对象生成了接口 ...

XiYoumengshen的博客 8569

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

上一篇: C++字符串分割替换 ubuntu版本
下一篇: maven的三种packaging方式
JSON_ZJS
博客等级 码龄9年 30粉丝 159原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值