• 什么是Java动态代理?(动态代理篇 一)


    简介

    Java动态代理是一种在运行时创建代理对象的技术,它可以在不修改原始类的情况下,对类的方法进行控制和扩展。常见应用场景:AOP(面向切面编程)、事务管理、权限控制、日志记录等等。

    特点

    1. 灵活性:动态代理可以在运行时创建代理对象,使得我们可以动态地对目标对象进行代理,而无需提前编写代理类。
    2. 可扩展性:通过动态代理,我们可以在不修改原始类的情况下,对其方法进行增强、添加额外的逻辑或进行其他操作。
    3. 代码复用:使用动态代理可以将一些通用的操作逻辑抽取出来,作为代理处理程序,从而实现代码的复用。
    4. 解耦合:动态代理可以将代理逻辑与具体的业务逻辑分离,使得代码更加清晰和可维护。

    Java动态代理的两种实现方式

    基于接口的动态代理(jdk动态代理)

    这种方式要求被代理的类实现一个接口。在运行时,通过Java的反射机制,动态生成一个代理类,该代理类实现了被代理类所实现的接口,并且在代理类的方法中添加了额外的逻辑,这种方式的代理类是通过Proxy类的静态方法newProxyInstance()来创建的。

    1. 定义一个接口和实现类:该接口包含了实现类(被代理类)的方法。

    2. 创建代理类,该类负责实现 invoke() 方法,在该方法中定义了对原始方法的增强逻辑。

    3. 使用Proxy类创建代理对象:使用 Proxy 类的静态方法 newProxyInstance() 来创建代理对象。
      该方法接受三个参数:ClassLoader,用于加载代理类;Class[] interfaces,指定被代理类所实现的接口;InvocationHandler,用于处理代理方法的调用。

    4. 调用代理对象的方法:通过代理对象调用方法时,实际上会调用 InvocationHandler 的 invoke() 方法。在该方法内部,会根据被调用的方法名称和参数,找到对应的 Method 对象,并通过反射机制调用原始对象的方法。(了解反射机制:Java反射链接

    基于类的动态代理(CGLIB动态代理)

    这种方式要求被代理的类不能是final类。在运行时,通过CGLIB库生成一个被代理类的子类,该子类继承了被代理类的所有方法,并且在子类的方法中添加了额外的逻辑,这种方式的代理类是通过Enhancer类来创建的。
    CGLIB库是第三方库需要导入jar包

    1. 定义目标类:首先,需要定义一个目标类,即需要被代理的类。

    2. 创建拦截器类:创建一个拦截器类,实现MethodInterceptor接口,实现拦截目标方法的逻辑。

    3. 创建Enhancer对象:使用CGLIB的Enhancer类创建一个Enhancer对象。

    4. 设置被代理类:使用Enhancer对象的setSuperclass方法设置被代理类的Class对象,表示要代理的目标类。

    5. 设置回调对象:使用Enhancer对象的setCallback方法设置回调对象,即实现了MethodInterceptor接口的拦截器类。

    6. 创建代理对象:使用Enhancer对象的create方法创建代理对象,该方法会根据被代理类和回调对象生成代理类的实例。

    7. 使用代理对象:通过代理对象调用目标类的方法。在调用过程中,拦截器类中的逻辑将被触发,实现对目标方法的拦截和增强。

    对比两种动态代理方式

    • 实现原理:基于类的动态代理通过继承目标类来实现代理,而基于接口的动态代理通过实现目标接口来实现代理。
    • 适用场景:基于类的动态代理适用于没有实现接口的类,而基于接口的动态代理适用于实现了接口的类。
    • 性能:基于类的动态代理相对于基于接口的动态代理来说,生成代理类的过程更复杂,性能上可能会稍慢一些。
    • 功能:基于类的动态代理可以代理目标类的所有非final方法,而基于接口的动态代理只能代理目标接口中定义的方法。

    下一篇:实现JDK动态代理
    以及------实现CGLIB动态代理

  • 相关阅读:
    数据安全中的访问安全包含哪些内容,如何实现数据访问安全
    docker镜像创建、删除等相关操作
    安装Hadoop以及HBase
    Linux 学习使用包管理器-实践和项目应用和命令行学习技巧与编程实践
    egg中的一些基本使用注意事项以及如何跨域(CORS)、JSONP、Proxy
    异地访问Oracle数据库的解决方案:利用内网穿透实现PL/SQL远程连接的建议与步骤
    leetcode之单调栈
    Vivado Synthesis - getting a Segmentation fault after using up a lot of memory.
    一文搞定,JMeter的三种参数化方式
    HDLbits: Lemmings2
  • 原文地址:https://blog.csdn.net/DU9999999/article/details/133719507