一、Cglib 代理模式的基本介绍

  1、静态代理和 JDK 代理模式都要求目标对象是实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理,这就是 Cglib 代理

  2、Cglib 代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展,有些地方也将 Cglib 代理归属到动态代理。

  3、Cglib 是一个强大的高性能的代码生成包,它可以在运行期扩展 java 类与实现 java 接口,它广泛的被许多 AOP 的框架使用,例如:Spring AOP,实现方法拦截

  4、在 AOP 编程中如何选择代理模式:

    (1)目标对象需要实现接口,用 JDK 代理;

    (2)目标对象不需要实现接口,用 Cglib 代理;

  5、Cglib 包的底层是通过使用字节码处理框架 ASM 来转换字节码并生成新的类;

 

二、Cglib 代理模式实现步骤

  1、需要引入 cglib 的 jar 文件

    

  2、在内存中动态构建子类,注意代理的类不能为 final,否则报错:java.lang.IllegalArgumentException;

  3、目标对象的方法如果是 final/static ,那么就不会被拦截,即不会执行目标对象额外的业务方法;

 

三、Cglib 代理模式应用实例

  1、要求

    将上一节的案例用 Cglib 代理模式实现

  2、UML 类图

    

  3、代码实现

    被代理类(目标对象)

1 public class TeacherDao {
2 
3     public String teach() {
4         System.out.println("老师授课中。。。我是cglib代理,不需要实现接口");
5         return "Hello";
6     }
7 }

 

    代理工厂:

 1 public class ProxyFactory implements MethodInterceptor {
 2 
 3     /**
 4      * 维护一个目标对象
 5      */
 6     private Object target;
 7 
 8     /**
 9      * 通过构造器,传入一个 被代理的 对象
10      * @param target
11      */
12     public ProxyFactory(Object target) {
13         this.target = target;
14     }
15 
16 
17     /**
18      *
19      * @return 返回一个代理对象(是target的代理对象)
20      */
21     public Object getProxyInstance() {
22         /**
23          * 1、创建一个工具类
24          * 2、设置父类
25          * 3、设置回调函数
26          * 4、创建子类对象,即代理对象
27          */
28 
29         Enhancer enhancer = new Enhancer();
30         enhancer.setSuperclass(target.getClass());
31         enhancer.setCallback(this);
32         return enhancer.create();
33     }
34 
35     /**
36      * 重写 intercept 方法,会调用目标对象的方法
37      * @param obj
38      * @param method
39      * @param args
40      * @param proxy
41      * @return
42      * @throws Throwable
43      */
44     @Override
45     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
46         System.out.println(obj.getClass());
47         System.out.println(proxy.getClass());
48         System.out.println("cglib代理模式~~开始");
49         Object invoke = method.invoke(target, args);
50         System.out.println("cglib代理模式~~提交");
51         return invoke;
52     }
53 }

 

    客户端:

 1 public class Client {
 2 
 3     public static void main(String[] args) {
 4         //创建目标对象
 5         TeacherDao teacherDao = new TeacherDao();
 6 
 7         //获取代理对象
 8         ProxyFactory proxyFactory = new ProxyFactory(teacherDao);
 9         TeacherDao proxyInstance = (TeacherDao)proxyFactory.getProxyInstance();
10         //执行代理对象的方法,触发 intecept 方法,从而实现对目标对象的调用
11         String res = proxyInstance.teach();
12         System.out.println(res);
13         System.out.println("proxyInstance=" + proxyInstance);
14 
15     }
16 }

 

posted on 2021-02-03 21:56  格物致知_Tony  阅读(251)  评论(0编辑  收藏  举报