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

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

相关推荐
美好的事情能不能发生在我身上15 分钟前
Hot100中的:贪心专题
java·数据结构·算法
myloveasuka23 分钟前
Java与C++多态访问成员变量/方法 对比
java·开发语言·c++
mygljx33 分钟前
【MySQL 的 ONLY_FULL_GROUP_BY 模式】
android·数据库·mysql
2301_8217005334 分钟前
C++编译期多态实现
开发语言·c++·算法
Andya_net40 分钟前
Spring | @EventListener事件机制深度解析
java·后端·spring
奥地利落榜美术生灬1 小时前
c++ 锁相关(mutex 等)
开发语言·c++
xixihaha13241 小时前
C++与FPGA协同设计
开发语言·c++·算法
lang201509281 小时前
18 Byte Buddy 进阶指南:解锁 `@Pipe` 注解,实现灵活的方法转发
java·byte buddy
重庆小透明1 小时前
【java基础篇】详解BigDecimal
java·开发语言
ID_180079054731 小时前
模拟1688商品详情的Python API实现,返回符合风格的JSON数据
开发语言·python·json