动态代理有两种实现方式:

  • JDK 动态代理(重要)
  • CGLIB 动态代理

1. CGLIB(了解)

使用继承机制,通过在子类中重写同名方法完成对父类的代理

其要求被代理的类不能为 final,方法也不能为 final

要求较宽松,只要类能被继承就能使用此方法,效率相对较高

2. JDK 动态代理

2.1 重要的类和方法

Proxy 类:用于创建代理对象的类,其中有很多静态方法

静态方法:newProxyInstance

1
2
3
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)

参数:

  • ClassLoader loader 要代理的目标对象的类加载器,负责向内存中加载对象,可以通过反射获取
  • Class<?>[] interfaces 目标对象实现的接口
  • InvocationHandler h 我们自己写的,代理类要完成的功能

返回值:

  • 代理对象

2.2 实现动态代理的步骤

  1. 创建接口,定义目标类要完成的功能
  2. 创建目标类实现接口
  3. 创建 InvocationHandler 接口的实现类,在 invoke 方法中完成代理类的功能
    • 调用目标方法
    • 增强功能
  4. 使用 Proxy 类的静态方法,创建代理对象,并返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//可以用这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {

//被代理的接口
private Object target;

public void setTarget(Object target) {
this.target = target;
}

//生成得到代理类
public Object getProxy() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}

//利用反射机制,处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target, args);
}
}