动态代理
2026年2月3日大约 2 分钟
动态代理
动态代理的思想就是,将原代码缺少的功能,通过代理类在运行时动态地补充上去,而不需要修改原代码,来达到增强原代码功能的目的。
如何创建代理
Java中创建动态代理是通过java.lang.reflect.Proxy类及其方法来实现的。
主要步骤如下:
- 创建一个代理类。
- 使用
Proxy类的静态方法newProxyInstance创建代理实例。Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h):该方法用于创建一个动态代理实例。- 参数1:
ClassLoader loader:指定代理类的类加载器,通常使用目标类的类加载器。 - 参数2:
Class<?>[] interfaces:指定代理类要实现的接口列表,通常是目标类所实现的接口。 - 参数3:
InvocationHandler h:指定一个InvocationHandler接口的实现类,用于处理代理实例的方法调用(就是代理需要做的事情)。
- 参数1:
- 实现
InvocationHandler接口,定义代理类需要执行的具体操作。InvocationHandler接口:该接口定义了一个invoke(Object proxy, Method method, Object[] args)方法,用于处理代理实例的方法调用。invoke方法的参数:- 参数1:
Object proxy:代理实例本身。 - 参数2:
Method method:被调用的方法对象。 - 参数3:
Object[] args:调用方法时传入的参数数组。
- 创建代理实例,并通过代理实例调用方法。
- 通过代理实例调用方法时,实际上会调用
InvocationHandler接口的invoke方法,从而实现对原方法的增强。
示例代码
下面是一个简单的动态代理示例代码,目的是计算UserService各方法的耗时:
// 定义一个接口,比如下面是用户功能的Service接口
interface UserService {
void addUser(String name);
}
// 实现接口的具体类
class UserServiceImpl implements UserService {
@Override
public void addUser(String name) {
System.out.println("添加用户: " + name);
}
}// 创建一个代理类
class ProxyUtil {
public static <T> T createProxy(T target){
T proxy = (T) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在调用目标方法前可以添加增强功能
long start = System.currentTimeMillis();
System.out.println("开始计时...");
// 调用目标方法
Object result = method.invoke(target, args);
// 在调用目标方法后可以添加增强功能
long end = System.currentTimeMillis();
System.out.println(method.getName() + "方法执行耗时: " + (end - start) + "毫秒");
return result;
}
}
);
return proxy;
}
}