0%

Java 动态代理(三):cglib 动态代理

1. Java SDK 动态代理的局限

  • Java SDK 动态代理的局限在于,它只能为接口创建代理,返回的代理对象也只能转换到某个接口类型
  • 如果一个类没有接口,或者希望代理非接口中定义的方法,那就没有办法了

2. cglib 动态代理的作用

  • 如果一个类没有接口,或者希望代理非接口中定义的方法,可以使用一个第三方类库 cglib (https://github.com/cglib/cglib)
  • Spring、Hibernate 等都使用了 cglib 类库

3. 写一个 cglib 动态代理 Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class SimpleCGLibDemo {
static class RealService { //被代理的实际的类,没有接口
public void sayHello() {
System.out.println("hello");
}
}

//MethodInterceptor 接口 类似于 Java SDK 中的 InvocationHander,与 InvocationHandler 不同的是:SimpleInterceptor 中没有被代理的对象
static class SimpleInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("entering " + method.getName());
//注意,不能这样调用:Object result = method.invoke(object, args); 否则会造成死循环
Object result = proxy.invokeSuper(object, args); //调用被代理类的方法
System.out.println("leaving " + method.getName());
return result;
}
}

private static <T> T getProxy(Class<T> cls) { //生成代理对象
Enhancer enhancer = new Enhancer(); //cglib 的 Enhancer 类
enhancer.setSuperclass(cls); //设置被代理的类
enhancer.setCallback(new SimpleInterceptor()); //设置被代理类的 public 非 final 方法被调用时的处理类,转换为调用 SimpleInterceptor 的 intercept 方法
return (T) enhancer.create();
}

public static void main(String[] args) throws Exception {
RealService proxyService = getProxy(RealService.class); //没有创建被代理的对象,创建的对象直接就是代理对象
proxyService.sayHello();
}
}
-------------------- 本文结束感谢您的阅读 --------------------