Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >java学习笔记(中级篇)—JDK动态代理

java学习笔记(中级篇)—JDK动态代理

作者头像
chlinlearn
发布于 2019-09-12 11:15:15
发布于 2019-09-12 11:15:15
33000
代码可运行
举报
文章被收录于专栏:java老实人java老实人
运行总次数:0
代码可运行

一、什么是代理模式

相信大家都知道代理商这个概念,在商业中,代理商无处不在。假设你要去买东西,你不可能去找真正的厂家去买,也不可能直接跟厂家提出需求,代理商就是这中间的一桥梁,连接买家和厂商。你要买或者定制什么产品,需要什么规格样式和价格的直接跟代理商沟通就好了,由代理商与真实的厂商沟通,这样买家有什么问题都可以咨询代理商,真实厂商也就可以专心做产品,不需要管其他事务了,买家也插手不了厂商的事。

在以上的关系中,厂商就是被代理对象,代理商就是代理对象,而买家就是调用者了。java中有多种动态代理的技术,包括JDK、CGLIB、Javassist等,这里我会拿CGLIB与JDK动态代理作比较。

二、意义

动态代理的意义就是在与生成一个占位(代理对象),来代理真实对象,从而达到控制真实对象的目的。要了解动态代理,首先要具备反射的知识。

三、实现动态代理的步骤

代理的实现分为两个主要步骤:

1.代理对象和真实对象建立代理关系

2.实现代理对象的逻辑方法

四、JDK动态代理

JDK动态代理,JDK自带的功能,在java.lang.reflect.*包中。要实现JDk动态代理,必须要借助接口才能产生代理对象。

1.先来定义一个简单的接口HelloWorld.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface HelloWorld {
    void sayHello();
}

2.HelloWorld的实现类HelloWorldImpl.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class HelloWorldImpl implements HelloWorld {
    @Override
    public void sayHello() {
        System.out.println("hello world");
    }
}

3.建立代理关系,必须实现接口InvocationHandler。invoke是接口里唯一需要实现的方法,里面实现的代理逻辑,当代理对象调度方法时,就会映射到invoke方法来,实际是通过反射来实现的。而bind()方法就是建立代理关系,通过Proxy的newProxyInstance来创建代理对象,第一个参数类加载器,第二个参数下挂的接口,第三个参数则是实现了代理逻辑方法invoke的类。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkProxy implements InvocationHandler {
    //真实对象
    private Object target = null;

    /**
     * 建立真实对象与代理对象之间的关系
     * @param target 传入真实对象
     * @return
     */
    public Object bind(Object target){
        this.target = target;
        return Proxy.newProxyInstance
            (target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }

    /**
     *  代理逻辑
     * @param proxy 代理对象
     * @param method 当前调度的方法
     * @param args 调度方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("进入代理逻辑方法");
        System.out.println("在调用真实对象之前的服务");
        Object object = method.invoke(target,args);
        System.out.println("在调用真实对象之后的服务");
        return object;
    }
}

4.测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import org.junit.Test;

public class JdkProxyTest {

    @Test
    public void test_JdkProxy(){
        JdkProxy proxy = new JdkProxy();
        HelloWorld helloWorld = null;
        try {
            helloWorld = (HelloWorld) proxy
                .bind(Class.forName
            ("com.xcl.ssm.chapter2.jdkproxy.HelloWorldImpl")
                            .newInstance());
        } catch (Exception e) {
            e.printStackTrace();
        }
        helloWorld.sayHello();
    }
}

五、CGLIB动态代理

上面说JDK动态代理的实现必须借助接口才能实现,而CGLIB则不用,只需要有一个非抽象类即可。我们以上面的HelloWorldImpl类为例,现在没有HelloWorld接口了。JDK动态代理必须要实现invocationHandler接口,CGLIB则必须要实现MethodInterceptor接口,里面也只有一个需要实现的方法intercept(),需要在里面实现代理逻辑。写代码之前记得导包哦,这是第三方提供的技术。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class CglibProxy implements MethodInterceptor {

    /**
     *  生成CGLIB代理对象
     * @return
     */
    public Object getProxy(Class clz){
        //CGLIB增强类对象
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clz);
        //设置当前对象为代理逻辑对象
        enhancer.setCallback(this);
        //生成并返回代理对象
        return enhancer.create();
    }

    /**
     *  代理逻辑方法
     * @param proxy 代理对象
     * @param method 方法
     * @param args 参数
     * @param methodProxy 方法代理
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("调用真实对象前");
        //通过反射调用真实对象的方法
        Object obj = methodProxy.invokeSuper(proxy,args);
        System.out.println("调用真实对象后");
        return obj;
    }
}

六、总结

要真正的参透动态代理就要非常熟悉反射机制,从以上的代码可以得知,动态代理的底层实现还是基于反射的,我们知道反射是很消耗性能的,这带来了一些性能问题,但是为了开发上的简便,这种牺牲是值得的。我们学的框架,比如spring,mybatis等,都大量使用了动态代理技术,有兴趣的童鞋可以去阅读源码(表示本人也不是看过很多源码),这里面用到了很多的设计模式,对提高自己的代码水平很有帮助。好啦,就说到这里吧~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring高手之路17——动态代理的艺术与实践
动态代理是一种强大的设计模式,它允许开发者在运行时创建代理对象,用于拦截对真实对象的方法调用。这种技术在实现面向切面编程(AOP)、事务管理、权限控制等功能时特别有用,因为它可以在不修改原有代码结构的前提下,为程序动态地注入额外的逻辑。
砖业洋__
2024/04/13
4610
Spring高手之路17——动态代理的艺术与实践
SSM框架中十分常用的设计模式:动态代理
👆点击“博文视点Broadview”,获取更多书讯 本文介绍的是SSM框架中十分常用的设计模式,所以开发者掌握它十分必要。 动态代理和责任链无论在Spring还是MyBatis中都有重要的应用,只要随着本书的例子多写代码,反复体验,就能掌握。在分析Spring AOP和MyBatis技术原理时,我们还会不断提及它们,它们适用范围广,值得读者认真研究。 代理模式的意义在于生成一个占位(又称代理对象),来代理真实对象(又称目标对象),从而控制真实对象的访问。 先来谈谈什么是代理模式。 假设这样一个场景,你的公
博文视点Broadview
2023/05/06
2220
SSM框架中十分常用的设计模式:动态代理
【小家Java】JDK动态代理技术,你真学会了吗?(Proxy、ProxyClassFactory)
动态代理技术,相信我们都并不陌生。特别是在Spring框架内,大量的使用到了反射以及动态代理技术。但是如果我们只是停留在平时的运用阶段,此篇文章你其实是可以跳过的,因为反射、代理技术一般都只有在框架设计中才会使用到,业务开发是不用接触的。
YourBatman
2019/09/03
4400
【小家Java】JDK动态代理技术,你真学会了吗?(Proxy、ProxyClassFactory)
深入解析:Cglib与JDK动态代理的实现原理、区别及性能对比
在Java开发中,动态代理是一种强大的技术,它允许在运行时创建代理对象以添加行为,而无需修改原始类的代码。JDK动态代理和Cglib是两种主要的动态代理实现方式。本文将深入探讨它们的实现原理、区别、劣势以及性能对比。
AI码师
2024/05/29
3.2K0
深入解析:Cglib与JDK动态代理的实现原理、区别及性能对比
jdk动态代理和cglib动态代理详解
如上图,代理模式可分为动态代理和静态代理,我们比较常用的有动态代理中的jdk动态代理和Cglib代理,像spring框架、hibernate框架中都采用了JDK动态代理,下面将结合代码阐述两种代理模式的使用与区别。
全栈程序员站长
2022/08/29
7200
jdk动态代理和cglib动态代理详解
Spring的两种动态代理Jdk与Cglib
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调InvokeHandler来处理。 而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。 1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP 3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
全栈程序员站长
2022/08/04
7430
Spring的两种动态代理Jdk与Cglib
JDK之动态代理(JDK与CGLIB)与静态代理
代理类在程序运行时创建的代理方式被称为动态代理 静态代理中,代理类是自己定义好的,在程序运行之前就已经编译完成。然而动态代理,代理类并不是在Java代码中定义的,而是运行时根据我们在Java代码中的指示动态生成的。相比较静态代理,动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法,比如想要在每个代理方法前都加上一个处理方法,静态代理就需要在每个类内部加上这个方法
才疏学浅的木子
2022/11/28
2220
JDK之动态代理(JDK与CGLIB)与静态代理
AOP中的JDK动态代理与CGLIB动态代理:深度解析与实战
这里推荐一篇实用的文章:《Java 读取寄存器数据的实现与应用》,作者:【喵手】。
小马哥学JAVA
2024/11/21
2260
JDK动态代理
这里是最简单的Java接口和实现类的关系,此时可以开始动态代理了,一般会分为两个步骤:第一是建立代理对象和真实服务对象的代理和被代理关系,第二步是实现代理对象具体方法的逻辑。
itlemon
2020/04/03
5320
jdk动态代理和cglb动态代理
静态代理是在编译时就确定了代理类的代码,在程序运行前就已经存在了代理类的class文件。代理类与委托类的关系在编译时就已经确定,因此被称为静态代理。在静态代理中,代理类需要实现与委托类相同的接口或者继承委托类的父类,以便能够对委托类进行代理操作。
一个风轻云淡
2023/10/15
2310
jdk动态代理和cglb动态代理
JDK动态代理和CGLIB动态代理
Java动态代理是一种在运行时创建代理对象的技术,它允许开发者在不修改目标类代码的情况下,通过代理类对目标类的实例方法进行增强或拦截。动态代理的核心价值在于能够在程序运行阶段动态地生成一个实现了预定义接口的新类,这个新类就是所谓的“代理类”。
程序猿川子
2025/02/27
1750
JDK动态代理和CGLIB动态代理
Java代理相关:JDK动态代理、CGLIB动态代理
代理(Proxy)是一种设计模式,提供了对目标对象另外的一种访问方式。可以在目标对象实现的基础上,增加额外的功能操作,即扩展目标对象的功能。
lpe234
2020/07/27
4320
【面试系列】JDK动态代理和CGLIB静态代理 - Java技术债务
是否在面试过程中经常被问到Spring的代理的问题:比如说几种代理方式?两种代理方式的区别?或者问为什么JDK动态代理只能代理接口?
Java技术债务
2024/06/21
1220
【面试系列】JDK动态代理和CGLIB静态代理 - Java技术债务
Java 动态代理详解
动态代理在Java中有着广泛的应用,比如Spring AOP、Hibernate数据查询、测试框架的后端mock、RPC远程调用、Java注解对象获取、日志、用户鉴权、全局性异常处理、性能监控,甚至事务处理等。
小旋锋
2019/01/21
1.1K0
Java两种动态代理JDK动态代理和CGLIB动态代理[通俗易懂]
代理模式是23种设计模式的一种,他是指一个对象A通过持有另一个对象B,可以具有B同样的行为的模式。为了对外开放协议,B往往实现了一个接口,A也会去实现接口。但是B是“真正”实现类,A则比较“虚”,他借用了B的方法去实现接口的方法。A虽然是“伪军”,但它可以增强B,在调用B的方法前后都做些其他的事情。Spring AOP就是使用了动态代理完成了代码的动态“织入”。
全栈程序员站长
2022/07/02
3660
Java两种动态代理JDK动态代理和CGLIB动态代理[通俗易懂]
java 代理模式-静态代理与动态代理
    举个例子吧:我们生活中的租房问题。假如我们去租个房子,我们大多数情况下是不会知道房主(就是真正租房,一手货源)的,我们是不是都是先去某些租房平台,或者去找当地的中介去询问何时的房子。我们通过九牛二虎之力在中介那里找到了个物美价廉的房子后,你的租金是不是交给了中介,中介还会收取一些额外的推荐费啦,押金啦、手续费等之类的,那么好,这样的一小段,就已经出来了其中两大核心对象了。
Arebirth
2019/09/24
4330
java 代理模式-静态代理与动态代理
基于JDK动态代理的自定义拦截器
接口中定义了三个方法,分别是:前置方法、后置方法和环绕方法(此叫法类似Spring AOP中的前置通知、后置通知以及环绕通知)。三个方法拥有相同的参数:第一个参数是动态代理对象,第二个是真实服务对象,第三个是方法对象,第四个是方法需要的参数集合。
itlemon
2020/04/03
1.2K0
jdk静态代理,jdk动态代理,cglib动态代理
代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道。如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法。如果公司卖多少钱,代理商也卖多少钱,那么代理商就赚不了钱。所以代理商在调用公司的卖方法后,加上自己的利润然后再把产品卖给客户。而客户部直接跟公司打交道,或者客户根本不知道公司的存在,然而客户最终却买到了产品。
互扯程序
2019/07/01
5120
jdk静态代理,jdk动态代理,cglib动态代理
动态代理技术的运用
“ 在前一篇文章我们了解了Spring AOP的简单运用,我们发现面向切面编程的核心是动态代理,我们这篇文章主要就是看一下:JDK自带的动态代理和CGLIB的动态代理”
每天学Java
2020/06/02
2980
通俗易懂讲解一下代理模式
维基百科所说的优点抽象,这里我们简单来讲就是通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。
Dream城堡
2019/10/28
5020
通俗易懂讲解一下代理模式
相关推荐
Spring高手之路17——动态代理的艺术与实践
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验