InvocationHandler 例子

2025/10/14

这里展示一个手动用 jdk 代理创建代理对象的例子。

一、自己的业务方法

public interface SimpleInterface {
    String sayHello(String name);
    int calculate(int a, int b);
}


public class SimpleInterfaceImpl implements SimpleInterface {

    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }

    @Override
    public int calculate(int a, int b) {
        return a + b;
    }
}

二、实现 InvocationHandler

/**
 * 自定义的 InvocationHandler,用于添加日志功能
 */
public class LoggingInvocationHandler implements InvocationHandler {
    
    private final Object target; // 被代理的目标对象
    
    public LoggingInvocationHandler(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 方法调用前的日志
        System.out.println("=== 方法调用开始 ===");
        System.out.println("调用方法:" + method.getName());
        if (args != null) {
            System.out.println("方法参数:" + java.util.Arrays.toString(args));
        }
        
        long startTime = System.currentTimeMillis();
        
        try {
            // 调用目标对象的方法
            Object result = method.invoke(target, args);
            
            long endTime = System.currentTimeMillis();
            
            // 方法调用后的日志
            System.out.println("方法返回值:" + result);
            System.out.println("方法执行时间:" + (endTime - startTime) + "ms");
            System.out.println("=== 方法调用结束 ===\n");
            
            return result;
        } catch (Exception e) {
            System.out.println("方法调用异常:" + e.getMessage());
            System.out.println("=== 方法调用结束 ===\n");
            throw e;
        }
    }
}

三、测试验证


public class ProxyExample {
    
    public static void main(String[] args) {
        // 1. 创建目标对象
        SimpleInterface target = new SimpleInterfaceImpl();
        
        // 2. 创建 InvocationHandler
        LoggingInvocationHandler handler = new LoggingInvocationHandler(target);
        
        // 3. 使用 Proxy.newProxyInstance 创建代理对象
        SimpleInterface proxy = (SimpleInterface) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),  // 类加载器
            target.getClass().getInterfaces(),   // 接口数组
            handler                              // InvocationHandler
        );
        
        // 4. 使用代理对象调用方法
        System.out.println("=== 使用代理对象调用方法 ===");
        
        // 调用 sayHello 方法
        String result1 = proxy.sayHello("张三");
        System.out.println("最终结果:" + result1);
        
        // 调用 calculate 方法
        int result2 = proxy.calculate(10, 20);
        System.out.println("最终结果:" + result2);
        
        // 5. 对比:直接调用目标对象(无代理)
        System.out.println("\n=== 直接调用目标对象(无代理) ===");
        String directResult1 = target.sayHello("李四");
        System.out.println("直接调用结果:" + directResult1);
        
        int directResult2 = target.calculate(5, 15);
        System.out.println("直接调用结果:" + directResult2);
    }
}

运行结果