动态代理 设计模式
JDK 动态代理的核心实现公式可以提取为以下结构,主要包含 3 个关键部分:
- 代理对象创建(
Proxy.newProxyInstance()
) - 类加载器与接口指定
- InvocationHandler 匿名实现(增强逻辑)
核心要素解析:
三参数固定写法
- 类加载器:
target.getClass().getClassLoader()
- 接口数组:
target.getClass().getInterfaces()
- 处理器:
new InvocationHandler() { ... }
- 类加载器:
增强逻辑固定结构
try {// 前置增强// 执行目标方法// 后置增强 } catch (Exception e) {// 异常增强 } finally {// 最终增强 }
核心方法
Proxy.newProxyInstance()
:创建代理对象的入口method.invoke(target, args)
:反射调用目标对象的方法
动态代理类
return Proxy.newProxyInstance(classLoader, interfaces, handler);
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** JDK动态代理通用模板*/
public class DynamicProxyTemplate {// 获取目标对象的代理对象public static Object getProxyInstance(Object target) {// 1. 类加载器:使用目标对象的类加载器ClassLoader classLoader = target.getClass().getClassLoader();// 2. 接口数组:目标对象实现的所有接口Class<?>[] interfaces = target.getClass().getInterfaces();// 3. 增强逻辑:InvocationHandler匿名实现InvocationHandler handler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;try {// 前置增强:方法执行前的逻辑beforeEnhance(method, args);// 执行目标方法(核心业务逻辑)result = method.invoke(target, args);// 后置增强:方法正常返回后的逻辑afterReturnEnhance(method, result);} catch (Exception e) {// 异常增强:方法抛出异常时的逻辑exceptionEnhance(method, e);} finally {// 最终增强:无论是否异常都会执行的逻辑finallyEnhance(method);}return result;}};// 创建并返回代理对象return Proxy.newProxyInstance(classLoader, interfaces, handler);}// 前置增强(示例方法)private static void beforeEnhance(Method method, Object[] args) {System.out.println("方法[" + method.getName() + "]执行前,参数:" + Arrays.toString(args));}// 后置返回增强(示例方法)private static void afterReturnEnhance(Method method, Object result) {System.out.println("方法[" + method.getName() + "]执行完成,返回值:" + result);}// 异常增强(示例方法)private static void exceptionEnhance(Method method, Exception e) {System.out.println("方法[" + method.getName() + "]执行异常:" + e.getMessage());}// 最终增强(示例方法)private static void finallyEnhance(Method method) {System.out.println("方法[" + method.getName() + "]执行结束");}
}
package com.atguigu.spring.aop.proxy.dynamic;import com.atguigu.spring.aop.log.LogUtils;import java.lang.reflect.Proxy;
import java.util.Arrays;/*** 动态代理: JDK动态代理;* 强制要求,目标对象必有接口。代理的也只是接口规定的方法。**/
public class DynamicProxy {//获取目标对象的代理对象public static Object getProxyInstance(Object target) {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),(proxy, method, args) -> {String name = method.getName();//记录开始LogUtils.logStart(name, args);Object result = null;try{result = method.invoke(target, args);//记录返回值LogUtils.logReturn(name, result);}catch (Exception e){//记录异常LogUtils.logException(name, e);}finally {//记录结束LogUtils.logEnd(name);}return result;});}
}
不需要单独写类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;// 1. 定义接口
interface Calculator {int add(int a, int b);
}// 2. 实现接口的目标类
class MyCalculator implements Calculator {@Overridepublic int add(int a, int b) {return a + b;}
}public class DynamicProxyDemo {public static void main(String[] args) {// 目标对象Calculator target = new MyCalculator();// 直接创建代理对象(无需单独编写代理类)Calculator proxy = (Calculator) Proxy.newProxyInstance(target.getClass().getClassLoader(), // 类加载器target.getClass().getInterfaces(), // 接口数组new InvocationHandler() { // 匿名内部类实现增强逻辑@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法[" + method.getName() + "]开始,参数:" + Arrays.toString(args));// 调用目标方法Object result = method.invoke(target, args);System.out.println("方法[" + method.getName() + "]结束,结果:" + result);return result;}});// 测试代理对象proxy.add(10, 20);}
}