• 第四节:代理模式——cglib代理


    一、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 }
  • 相关阅读:
    典型分布式系统分析:MapReduce
    linux下如何查看自己都装了什么服务
    docker
    linux的命令操作
    IDEA去除掉虚线,波浪线,和下划线实线的方法
    在linux下安装配置rabbitMQ详细教程
    在linux下安装配置rabbitMQ详细教程
    Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数
    shell之startup
    shell脚本特殊变量($0、$1、$2、 $?、 $# 、$@、 $*)
  • 原文地址:https://www.cnblogs.com/niujifei/p/14369959.html
Copyright © 2020-2023  润新知