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。
  • 动态代理的性能开销比静态代理稍大,因为每次方法调用都涉及反射。
  • 动态代理提供了强大的灵活性和可扩展性,但应谨慎使用,以避免不必要的复杂性。

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

相关推荐
摇滚侠5 分钟前
VMvare 虚拟机 Oracle19c 安装步骤,远程连接 Oracle19c,百度网盘安装包
java·oracle
梁萌9 分钟前
idea报错找不到XX包的解决方法
java·intellij-idea·启动报错·缺少包
Agent产品评测局16 分钟前
生产排期与MES/ERP系统打通,实操方法详解 —— 2026企业级智能体自动化选型与实战指南
java·运维·人工智能·ai·chatgpt·自动化
cen__y18 分钟前
Linux07(信号01)
linux·运维·服务器·c语言·开发语言
scan72429 分钟前
长期记忆存储在数据库里
android
阿丰资源36 分钟前
基于Spring Boot的电影城管理系统(直接运行)
java·spring boot·后端
xingpanvip38 分钟前
星盘接口开发文档:星相日历接口指南
android·开发语言·前端·css·php·lua
guygg881 小时前
基于遗传算法的双层规划模型求解MATLAB实现
开发语言·matlab
呱牛do it1 小时前
企业级门户网站设计与实现:基于SpringBoot + Vue3的全栈解决方案(Day 8)
java
凯瑟琳.奥古斯特1 小时前
SQLAlchemy核心功能解析
开发语言·python·flask