返回顶部
首页 > 资讯 > 后端开发 > JAVA >Java——JDK动态代理
  • 581
分享到

Java——JDK动态代理

java开发语言 2023-08-31 18:08:33 581人浏览 八月长安
摘要

1.动态代理 1.1什么是动态代理? 动态代理(理解) 基于反射机制 举个例子,生活中一般在打官司的时候都会请代理律师,为什么要请律师呢?是因为开庭的时候大部人对于打官司没有经验,只会说出自己案件的陈述,并不会根据法律等争取自己权益

1.动态代理


1.1什么是动态代理?

动态代理(理解) 基于反射机制

举个例子,生活中一般在打官司的时候都会请代理律师,为什么要请律师呢?是因为开庭的时候大部人对于打官司没有经验,只会说出自己案件的陈述,并不会根据法律等争取自己权益的最大化,此时就可以请律师帮助自己不仅完成对案件的陈述,还能争取权益最大化。那么Java中也是一样,如果要对功能进行增强就可以使用动态代理。

我们知道spring是通过jdk或者CGLib实现动态代理的,今天我们讨论一下JDK实现动态代理的原理。

1.2动态代理的实现方式有几种?

  1. JDK动态代理
  2. CGLB动态代理

1.3动态代理的概念和优点

相比于静态代理(在静态代理中,对于类的每一个接口,我们都要单独写一个代理类),动态代理在创建代理对象上更加的灵活。

有需求,有问题,才会有解决方法和改进创新。那么产生动态代理的问题根源或者需求是什么呢?在静态代理中,由于每个接口都需要我们单独的写一个代理类,比较麻烦,因此我们就想,我们能不能写一个类,我们只需要把委托对象(目标对象),还有全部接口(共同行为,其实委托对象中就已经包含接口了)作为参数传给这个类的方法,然后这个方法就可以给我们返回一个我们想要的代理对象呢,并且这个代理对象可以给我们代理全部的共同行为,像是租房,结婚等?

  • 动态代理类的字节码在程序运行时由JAVA反射机制动态产生。会根据需要,通过反射机制,在程序运行期动态的为目标对象(委托对象)创建代理对象,无需程序员手动编写代理对象所属类的代码。
  • 动态代理不仅简化了编程工作,而且提高了软件系统的可扩展性,因为反射机制的使用使得可以生成任意类型的代理对象。
  • 动态代理的实现方式有两种,分别是:JDK动态代理和CGLIB动态代理。
  • 动态代理的目标对象是不固定的(也就是说把任何一个目标对象或者说是委托对象作为参数传递给生成代理对象的对象的方法,都会给我们返回一个我们想要的代理对象);使用动态代理以后,会在应用程序执行的时候,动态的创建目标对象代理对象依然会增强目标对象的行为;

2.JDK动态代理的概念和特点

先说一个需要注意的点:JDK动态代理的目标对象必须要有接口实现,也就是说:委托类必须要继承接口。

在JDK中,有一个Proxy类(名词,代理人)。Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态的生成实现类(对这个类的其他方法我了解的也不是很多,我们可以看JDK的在线api文档,百度搜一下好像挺多的)。这个类提供的有一个静态方法:newProxyInstance()方法。这个方法的目的就是给我们的目标对象(委托对象)返回一个代理对象。

newProxyInstance()方法需要有三个参数:

  1. 类加载器(ClassLoader对象)
  2. 接口集合(一个Interface对象的数组,就是需要代理对象代理那些共同行为,也是委托对象继承的共同行为接口)
  3. 一个InvocationHandler接口对象(当然可以是它的一个实现类对象)。这个接口中有一个invoke()方法。invoke()方法起到的作用很大,当代理对象调用共同行为方法的时候,invoke()方法就会被自动调用执行。

下面粘贴一张图片:

2.1动态代理的介绍

img

  1.  动态代理是指代理类对象在程序运行时由JVM根据反射机制动态生成的。动态代理不需要定义代理类的,java源文件。
  2. 动态代理其实就是jdk运行期间,动态创建class字节码并加载到JVM。
  3. 动态代理的实现方式常用的有两种:使用JDK代理,与通过CGLlB动态代理。

2.2动态代理的实现

  1. jdk动态代理(理解):使用java反射包中的类和接口实现动态代理的功能,反射包java.lang.reflect,里面有三个类:InvocationHandler,Method,Proxy
  2. cglib动态代理(了解): cglib是第三方的工具库,创建代理对象
  • cglib的原理是继承,cglib通过继承目标类,创建它的子类,在子类中
    重写父类中同名的方法,实现功能的修改。
  • 因为cglib是继承,重写方法,所以要求目标类不能是fina1的,方法也不能是final的。cglib的要求目标类比较宽松,只要能继承就可以了。cglib在很多的框架中使用,
    比如mybatis,spring框架中都有使用

2.3CGLB动态代理

CGLB动态代理即Code Generation Library,是一个开源的第三方工具库,其原理是继承,去生成目标类的子类对象,这样对子类的功能进行增强。但是要求:目标类不能用final修饰,目标类中的方法也不能被final修饰。

2.4动态代理的效率

CGLB动态代理的效率要大于JDK动态代理的效率。

3.为什么使用JDK动态代理?

3.1代码案例:

  1. 请看如下例子,一个音乐人的本质会唱歌、会跳舞、会rap等,但是观众进入演唱会所时首先要交门票,最基本的实现方法是直接对方法进行改造,添加对应的功能。
    package com.zhao.service.impl;import com.zhao.service.Actor;public class CXK implements Actor {    @Override    public void sing(int money) {        System.out.println("听"+money);    }    @Override    public String dance() {        System.out.println("吹灰舞");        return "发放签名";    }    @Override    public void rap() {        System.out.println("练习时长两年");    }}
  2. 这样操作发现出现了大量重复的代码,如果有十处、一百处需要同样的处理那么代码需要重复十次、一百次。当然我们可以把这些功能封装成一个增强方法,然后在功能方法中进行调用,但是也出现了方法的十处、一百处的调用操作,一旦增强方法名字改变,就需要完成所有调用处代码的修改。或者有一天不需要这些增强操作了,就再次需要在这十处、一百处删除方法调用。所以这种操作不适用于大型的项目开发的需求,此时我们就必须使用Java的动态代理机制。

在Java开发中如果一个类中的方法在基本功能之外需要进行功能扩充或者功能增强,如:事务控制、权限判断、日志记录等等操作,此时可以使用动态代理机制。

Java的JDK中Proxy类可以实现基于接口的动态代理,实现步骤示例如下:

  1. 因为Proxy类必须基于接口进行动态代理,所以首先创建接口,定义接口的规范,即功能方法的定义。
    package com.zhao.service;public interface Actor {   //唱歌    void sing(int money);    //跳舞    String dance();    //rap    void rap();}
  2. 定义实现接口的子类,实现接口定义的方法,此方法只需要把核心功能实现即可,其他增强的操作可以在代理类中实现。
    package com.zhao.service.impl;import com.zhao.service.Actor;public class CXK implements Actor {    @Override    public void sing(int money) {        System.out.println("听"+money);    }    @Override    public String dance() {        System.out.println("吹灰舞");        return "发放签名";    }    @Override    public void rap() {        System.out.println("练习时长两年");    }}
  3. 定义代理类,在代理类中对被代理对象进行方法增强。
    package com.zhao.advice;import com.zhao.service.Actor;import com.zhao.service.impl.CXK;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class JJGS {    public static void main(String[] args) {        //1.创建被代理类的对象----具体的人物cxk        Actor cxk=new CXK();        //2.创建代理对象--- 具体某人为上面cxk                Actor jjr=(Actor) Proxy.newProxyInstance(CXK.class.getClassLoader(), CXK.class.getInterfaces(), new InvocationHandler() {                        @Override            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                //被代理对象方法的执行,并获得返回值                Object result=null;                result=method.invoke(cxk,args);                System.out.println("演出后的增强:结算费用并纳税");                return result;            }        });        //3.执行功能//        jjr.sing(5000);        String dance = jjr.dance();        System.out.println(dance);    }}

  测试结果:

3.2基于子类的CGLib动态代理,可以使用Enhancer类完成直接对某个类进行动态代理。具体操作步骤如下:

  1. 创建被代理的类,并且定义功能方法,只需要完成核心功能即可。
    package com.zhao.service.impl;public class Actor {    public void sing(int money) {        System.out.println("听" + money);    }    public String dance(int money) {        System.out.println("吹灰舞"+money);        return "发放签名";    }    public void rap(int money) {        System.out.println("练习时长两年"+money);    }}
  2. 定义代理类,使用Enhancer创建代理对象,对被代理对象进行方法增强。
    package com.zhao.advice;import com.zhao.service.impl.Actor;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 JJGss {    public static void main(String[] args) {        //1.被代理的对象        Actor actor=new Actor();        //2.使用CGLIb的Enhancer类创建代理对象        Actor proxyActor = (Actor) Enhancer.create(Actor.class, new MethodInterceptor() {            @Override            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {                String methodName=method.getName();                String money=args[0];                Object result=null;                if(methodName.equals("danceAct")){                    System.out.println("对方法执行前进性代理增强...");                    result=method.invoke(actor,money);                    System.out.println("对方法执行后进性代理增强...");                    return result;                }                return result;            }        });        //        proxyActor.dance(3000);    }}

来源地址:https://blog.csdn.net/m0_73671382/article/details/129876351

--结束END--

本文标题: Java——JDK动态代理

本文链接: https://lsjlt.com/news/386669.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java——JDK动态代理
    1.动态代理 1.1什么是动态代理? 动态代理(理解) 基于反射机制 举个例子,生活中一般在打官司的时候都会请代理律师,为什么要请律师呢?是因为开庭的时候大部人对于打官司没有经验,只会说出自己案件的陈述,并不会根据法律等争取自己权益...
    99+
    2023-08-31
    java 开发语言
  • java jdk动态代理详解
    jdk动态代理要对一个类进行代理,被代理的类必须实现至少一个接口,并且只有接口中的方法才能被代理。 jdk实现动态代理一般分为三步: 1. 编写接口和实现类。 2. 写一个处理器,该...
    99+
    2022-11-15
    java jdk 动态代理
  • Java如何实现JDK动态代理
    这篇文章主要讲解了“Java如何实现JDK动态代理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java如何实现JDK动态代理”吧!概念代理:为控制A对象,而创建出新B对象,由B对象代替执行...
    99+
    2023-07-02
  • jdk动态代理和cglib动态代理详解
    目录静态代理基于继承的方式实现静态代理基于聚合的方式实现静态代理继承与聚合方式实现的静态代理对比动态代理JDK动态代理如何实现一个HashMap的动态代理类?Cglib动态代理JDK...
    99+
    2024-04-02
  • java中JDK动态代理的原理是什么
    这篇文章将为大家详细讲解有关java中JDK动态代理的原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java可以用来干什么Java主要应用于:1. web开发;2. Android...
    99+
    2023-06-14
  • Java实现JDK动态代理的原理详解
    目录概念案例静态代理JDK动态代理模式原理分析真相大白概念 代理:为控制A对象,而创建出新B对象,由B对象代替执行A对象所有操作,称之为代理。一个代理体系建立涉及到3个参与角色:真实...
    99+
    2024-04-02
  • spring cglib 与 jdk 动态代理
    1. 概述JDK动态代理是利用java反射机制 生成一个实现接口的匿名类, 在调用具体方法前调用InvocationHandler来处理Cglib动态代理是 利用asm开源包 把被代理类的class文件加载进来 通过修改其字节码生成子类来处...
    99+
    2023-05-31
    spring cglib jdk
  • Java反射(JDK)与动态代理(CGLIB)详解
    目录一、反射二、动态代理1、JDK代理2、CGLIB代理3、JDK代理与CGLIB代理对比总结一、反射 概念:在运行状态中,对于任意的一个类,都能够知道这个类的所有字段和方法,对任意...
    99+
    2024-04-02
  • java动态代理(jdk与cglib)详细解析
    JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息...
    99+
    2022-11-15
    java jdk cglib
  • Java中JDK动态代理的超详细讲解
    目录1. 什么是动态代理?2.动态代理的实现方式有几种?3. JDK动态代理4. CGLB动态代理5.动态代理的效率6.为什么要使用动态代理呢?7. JDK动态代理详细使用介绍总结1...
    99+
    2022-11-13
    Java jdk动态代理 java动态代理原理 jdk动态代理是如何实现的
  • 深入浅析java 中JDK的动态代理类
    这期内容当中小编将会给大家带来有关深入浅析java 中JDK的动态代理类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。详解java JDK 动态代理类分析(java.lang.reflect.Proxy)...
    99+
    2023-05-31
    java jdk 动态代理类
  • Java JDK 动态代理的使用方法示例
    本文主要和大家分享介绍了关于Java JDK 动态代理使用的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:前言代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤...
    99+
    2023-05-31
    java jdk 动态代理
  • 深度剖析java中JDK动态代理机制
    摘要相比于静态代理,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定一组接口及目标类对象就能动态的获得代理对象。代理模式使用代理模式必须要让代理类和目标类实现相同的接口,客户端通过代理类来调用目标方法,代理类会将所有的方法调用...
    99+
    2023-05-31
    jdk 动态代理 ava
  • Java JDK与cglib动态代理有哪些区别
    本篇内容主要讲解“Java JDK与cglib动态代理有哪些区别”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java JDK与cglib动态代理有哪些区别”吧!一、说明sp...
    99+
    2023-07-05
  • JDK动态代理和CGLIB区别
    JDK动态代理和CGLIB区别1、JDK动态代理:利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。(相关视频教程分享:java视频...
    99+
    2020-11-10
    java教程 JDK CGLIB 区别
  • 通俗易懂 快速理解 JDK动态代理 和 cglib动态代理
    动态代理的实现方案有两种,JDK动态代理和CGLIB动态代理,区别在于JDK自带的动态代理,必须要有接口,而CGLIB动态代理有没有接口都可以。 JDK动态代理:JDK原生的实现方式,需要被代理的...
    99+
    2023-10-21
    java spring
  • 基于JDK动态代理原理解析
    目录1、回顾一下JDK动态代理的核心参数2、实现一个简单的动态代理①、定义接口Subject②、定义接口的实现类RealSubject③、定义代理对象创建工厂④、创建测试类,为tar...
    99+
    2023-05-18
    JDK动态代理原理 JDK动态代理 动态代理原理
  • 深入浅析java 中的JDK与cglib动态代理
    这篇文章将为大家详细讲解有关深入浅析java 中的JDK与cglib动态代理,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。java 动态代理实例详解1.jdk动态代理 package com...
    99+
    2023-05-31
    java jdk cglib
  • 纯手写实现JDK动态代理
    作者:张丰哲原文:https://www.jianshu.com/p/58759fef38b8前言在Java领域,动态代理应用非常广泛,特别是流行的Spring/MyBatis等框架。JDK本身是有实现动态代理技术的,不过要求被代理的类必须...
    99+
    2023-06-02
  • 在Java中实现JDK动态代理的原理是什么
    在Java中实现JDK动态代理的原理是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、什么是代理?代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对...
    99+
    2023-05-31
    java jdk 动态代理
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作