这里展示一个手动用 jdk 代理创建代理对象的例子。
- 定义业务接口及方法
- 自定义自己的 handler,设计好在方法前后要添加的逻辑
- 创建代理对象
- 触发代理对象
一、自己的业务方法
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);
}
}
运行结果
