java 动态代理实现

java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口实现。Proxy 类提供了创建动态代理类和实例的静态方法,而 InvocationHandler 接口需要用户实现,用于处理在代理实例上执行的方法调用。

实现步骤

  1. 定义一个或多个接口:被代理类需要实现的接口。
  2. 创建实现 InvocationHandler 接口的类 :在这个类中实现 invoke 方法,该方法将调用原始对象的对应方法,并可以在调用前后添加自定义的逻辑。
  3. 通过 Proxy 类的静态方法创建代理对象 :将接口类数组和实现了 InvocationHandler 接口的类的实例作为参数传递给 Proxy.newProxyInstance 方法。

示例

假设我们有一个接口 Greeting 和一个实现了该接口的类 SimpleGreeting,现在我们想要在不修改 SimpleGreeting 源代码的情况下,为其方法调用添加日志功能。

Greeting 接口

java 复制代码
public interface Greeting {  
    void sayHello(String name);  
}

SimpleGreeting 类

java 复制代码
public class SimpleGreeting implements Greeting {  
    @Override  
    public void sayHello(String name) {  
        System.out.println("Hello, " + name);  
    }  
}

InvocationHandler 实现

java 复制代码
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
  
public class GreetingInvocationHandler implements InvocationHandler {  
    private final Object target;  
  
    public GreetingInvocationHandler(Object target) {  
        this.target = target;  
    }  
  
    @Override  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
        System.out.println("Before method: " + method.getName());  
        Object result = method.invoke(target, args);  
        System.out.println("After method: " + method.getName());  
        return result;  
    }  
}

创建代理对象并测试

java 复制代码
import java.lang.reflect.Proxy;  
  
public class ProxyDemo {  
    public static void main(String[] args) {  
        Greeting realSubject = new SimpleGreeting();  
        Greeting proxyInstance = (Greeting) Proxy.newProxyInstance(  
                realSubject.getClass().getClassLoader(),  
                new Class<?>[] { Greeting.class },  
                new GreetingInvocationHandler(realSubject)  
        );  
  
        proxyInstance.sayHello("World");  
    }  
}

运行 ProxyDemomain 方法,将看到在调用 sayHello 方法前后分别输出了日志信息,而实际的方法调用则通过 InvocationHandlerinvoke 方法转发给了原始的 SimpleGreeting 实例。

注意事项

  • 动态代理主要用于代理接口,如果要代理类(没有实现接口),则需要使用其他技术,如 CGLIB。
  • 动态代理的性能开销比静态代理稍大,因为每次方法调用都涉及反射。
  • 动态代理提供了强大的灵活性和可扩展性,但应谨慎使用,以避免不必要的复杂性。

---- 文章由 文心一言 生成

相关推荐
程序员岳焱1 分钟前
Java 高级泛型实战:8 个场景化编程技巧
java·后端·编程语言
Humbunklung2 分钟前
Rust Floem UI 框架使用简介
开发语言·ui·rust
钢铁男儿11 分钟前
C# 类和继承(扩展方法)
java·servlet·c#
饮长安千年月17 分钟前
JavaSec-SpringBoot框架
java·spring boot·后端·计算机网络·安全·web安全·网络安全
移动开发者1号18 分钟前
Android 大文件分块上传实战:突破表单数据限制的完整方案
android·java·kotlin
代码匠心18 分钟前
从零开始学Flink:揭开实时计算的神秘面纱
java·大数据·后端·flink
移动开发者1号26 分钟前
单线程模型中消息机制解析
android·kotlin
jie1889457586634 分钟前
C++ 中的 const 知识点详解,c++和c语言区别
java·c语言·c++
网安INF39 分钟前
RSA加密算法:非对称密码学的基石
java·开发语言·密码学
明月*清风39 分钟前
c++ —— 内存管理
开发语言·c++