【Java 基础】30 JDK动态代理

2023-12-15 23:28:44


动态代理是一种重要的 设计模式,它允许在运行时生成代理类来代替实际的类。动态代理主要通过反射机制实现,为开发者提供了一种灵活且强大的方式来实现 AOP(面向切面编程)等功能。

1.定义

动态代理是一种在运行时生成代理类的机制,这些代理类在程序运行时创建,而不是在编译时静态定义。 JDK 动态代理主要基于 Java 的反射机制,通过在运行时创建代理类和对象,实现对实际类的代理。

动态代理通常用于在不修改原始类代码的情况下,向现有类添加额外的功能,例如日志记录性能监控事务处理等。

2.原理

JDK 动态代理的核心在于 java.lang.reflect 包中的 Proxy 类和 InvocationHandler 接口。代理类的创建过程主要包括以下步骤:

在这里插入图片描述

  • 定义接口: 定义一个业务接口,该接口将被动态代理类实现。
  • 实现 InvocationHandler 接口: 创建一个实现 InvocationHandler 接口的类,该类中包含了对原始类方法的代理逻辑。
  • 生成代理类: 使用 Proxy.newProxyInstance 方法生成代理类的实例,该方法需要传入类加载器、业务接口和 InvocationHandler 实现。
  • 调用代理方法: 通过代理类实例调用方法时,实际会调用到 InvocationHandler 中的 invoke 方法,从而执行代理逻辑。

3.使用

1)定义业务接口

interface Stu {
    void say(String name);
}

2)实现 InvocationHandler 接口

class HelloInvocationHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        // 增加前处理
        System.out.println("执行方法前: " + method.getName());

        // 执行原始方法 say
        System.out.println("Hello, " + args[0]);

        // 增加后处理
        System.out.println("执行方法后: " + method.getName());

        return null;
    }
}

3)生成代理类

public class Demo {
    public static void main(String[] args) {
        // 创建 InvocationHandler 实例
        HelloInvocationHandler invocationHandler = new HelloInvocationHandler();

        // 生成代理类实例
        Stu proxy = (Stu) Proxy.newProxyInstance(
                Stu.class.getClassLoader(),
                new Class[] { Stu.class },
                invocationHandler
        );

        // 调用代理方法
        proxy.say("Cheney");
    }
}

输出结果:

执行方法前: say
Hello, Cheney
执行方法后: say

在上述示例中,HelloInvocationHandler 类实现了 InvocationHandler 接口,通过在代理方法的前后添加日志记录,这也就是传说中的 AOP 面向切面编程的效果。

4.优点

  • 灵活性: 动态代理可以代理任意实现了接口的类,不受具体类的限制。
  • 简化代码: 动态代理可以避免编写大量重复的代理类代码,减少代码冗余。
  • 解耦合: 动态代理实现了代理逻辑和业务逻辑的解耦,使得代理类可以复用于不同的业务场景。

5.缺点

  • 只能代理接口: JDK 动态代理只能代理实现了接口的类,对于没有实现接口的类无法进行代理。
  • 性能相对较低: 由于动态代理是在运行时生成代理类,因此相比静态代理,其性能相对较低。

总结

JDK 动态代理是一种强大而灵活的设计模式,它通过在运行时生成代理类来实现对实际类的代理,为实现 AOP 等功能提供了便捷的方式。通过使用 Proxy 类和 InvocationHandler 接口,开发者可以轻松地创建动态代理。虽然 JDK 动态代理有一些限制,如只能代理实现了接口的类,性能相对较低等,但在大多数场景下,其优势远远大于缺点,使得它成为 Java 编程中不可或缺的一部分。

文章来源:https://blog.csdn.net/yanyc0411/article/details/134937862
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。