Java 动态代理是什么? 怎么实现动态代理?

2024-01-07 18:01:47

Java 动态代理是什么? 怎么实现动态代理?

Java 动态代理是一种在运行时创建代理类和实例的机制,它允许在调用实际方法之前或之后插入自定义的逻辑。动态代理是通过 Java 反射机制实现的,主要利用 java.lang.reflect.Proxy 类和 InvocationHandler 接口。

动态代理有两个关键组成部分:

  1. 接口: 被代理的类必须实现一个接口。
  2. InvocationHandler 接口: 提供了一个 invoke 方法,在该方法中可以定义在调用方法前后执行的逻辑。

以下是一个简单的动态代理示例:

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

// 定义接口
interface Hello {
    void sayHello();
}

// 实际类实现接口
class HelloImpl implements Hello {
    @Override
    public void sayHello() {
        System.out.println("Hello, world!");
    }
}

// 实现 InvocationHandler 接口,提供代理逻辑
class MyInvocationHandler implements InvocationHandler {
    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method invocation");
        Object result = method.invoke(target, args);
        System.out.println("After method invocation");
        return result;
    }
}

public class DynamicProxyExample {

    public static void main(String[] args) {
        // 创建实际对象
        Hello hello = new HelloImpl();

        // 创建 InvocationHandler 实例
        MyInvocationHandler handler = new MyInvocationHandler(hello);

        // 创建动态代理对象
        Hello proxyHello = (Hello) Proxy.newProxyInstance(
                Hello.class.getClassLoader(),
                new Class[]{Hello.class},
                handler
        );

        // 调用动态代理对象的方法
        proxyHello.sayHello();
    }
}

在这个示例中,Hello 是一个接口,HelloImpl 是接口的实际实现类。MyInvocationHandler 是一个实现了 InvocationHandler 接口的类,它提供了代理的逻辑。在 DynamicProxyExample 中,通过 Proxy.newProxyInstance 方法创建了一个动态代理对象,该对象实现了 Hello 接口,然后通过该代理对象调用方法时,会在实际方法执行前后插入自定义的逻辑。

需要注意的是,动态代理要求被代理的类必须实现一个接口,因为动态代理是基于接口的。如果被代理的类没有实现接口,可以考虑使用字节码生成工具,例如 CGLIB。

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