cglib动态代理 | 如何生成代理类、代理类内容解析

简介: cglib动态代理 | 如何生成代理类、代理类内容解析

简介

 CgLib(Code Generation Library)是一个针对java,且开源的代码生成类库,封装了ASM,ASM可以直接产生二进制class文件。CgLib能够在运行时动态地生成类的子类,常用于实现动态代理。


CGLib被广泛使用在基于代理的AOP框架(例如SpringAOP和dynaop)

hibernate使用CGLib对持久化对象创建代理。

本篇博客将从三个方面讲述:

  • cglib动态代理有什么优点
  • 如何生成代理类
  • 代理类内容解析

一、cglib动态代理有什么特点

特点 动态代理 静态代理
代理对象创建时间 运行时动态生成代理类 编码时编写代理类
代码维护 代理逻辑集中在一个通用的类中,易于维护和修改 代理逻辑分散在多个具体代理类中,增加了代码维护的复杂性

CgLib动态代理:

优点:

1.被代理的类不必须要实现一个接口,因为通过继承的方式重写被代理类方法

2.FastClass机制,不使用反射调用被代理方法,代码执行速度快

缺点:

1.无法重写的方法不能被cglib代理

2.生成代理类花费时间比较多,因为还要额外生成两个代理类(FastClass相关类),所以单例模式更适合cglib

二、Cglib如何生成代理类

  这就要涉及到源码了,Cglib提供生成的代理类的方式是调用Enhancer类的create方法,在创建代理类之前还有两个必要条件:

  1. superclass:被代理的类
  2. callback:设置回调的拦截器
    //生成一个增强器
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserService.class); //设置要代理的类
        enhancer.setCallback(new MyApiInterceptor()); //设置回调的拦截器数组
        // 创建代理对象
        Person person=enhancer.create();
        person.test();

  拦截器:

class MyApiInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("被代理方法执行前"); // 此处可以做一些操作
        Object result = proxy.invokeSuper(obj, args);//执行被代理方法
        System.out.println("被代理方法执行后" );  // 方法调用之后也可以进行一些操作
        return result;
    }
}

  被代理类:

class UserService {
  //方法必须能被重写,不能被final修饰
    public void test() {
        System.out.println("调用test方法了...");
    }
}

下面看Enhancer类的create方法做了什么:

1.调用Enhancer的createHelper()方法:

2.调用super.create(),也就是AbstractClassGenerator的create()方法:

  主要看下面的截图:data.get方法生成代理类、return那句返回了代理类对象。

生成代理类的具体代码:

  data.get是一个入口,主要看Enhancer的generate()方法

  以及Enhancer的generateClass()方法

  idea上写的java代码都是.java格式的,经过jvm的编译器编译会生成字节码文件(.class),Cglib使用asm直接生成字节码文件。字节码是由一条条的指令构成,专门学习过才看得懂,所以如何生成代理类不用过分关注,能看懂生成的代理类有哪些内容即可。


生成代理对象的具体代码:

Enhancer的createUsingReflection()方法

三、代理类内容解析

持久化代理类:

  Cglib生成的代理类放在内存中,通过dglib提供的调试命令可以将代理类持久化到硬盘。

-Dcglib.debugLocation=E:\project\common\CglibDemo\target\classes\   ##可以持久化到任意目录

重新启动程序执行代理逻辑,会发现指定路径生成了代理类:

代理类内容:

1.继承了Userservice类(被代理类)

2.重写了Userservice(被代理类)的test方法

3.重写了Object类能被重写的方法

Cglib动态代理和jdk动态代理

  CGLIB(Code Generation Library)和 JDK(Java Development Kit)中的动态代理是两种不同的实现方式,它们在实现原理和使用方式上存在一些区别。


原理:

 JDK动态代理是基于接口的代理。它使用Java的反射机制,在运行时创建一个实现指定接口的代理类。代理类实现了InvocationHandler接口,并将方法调用转发给InvocationHandler处理。

 CGLIB动态代理是基于继承的代理。它通过生成目标类的子类来实现代理。代理类继承了目标类,并重写了方法,从而实现了方法拦截和增强的功能。


使用方式:

 JDK动态代理要求目标类实现一个接口,代理对象实现了与目标类相同的接口。通过Proxy类的静态方法创建代理对象,将目标对象和InvocationHandler实例传入。

 CGLIB动态代理不要求目标类实现接口。通过Enhancer类创建代理对象,将目标对象设置为父类,同时设置MethodInterceptor实例作为拦截器。


性能:

 JDK动态代理在调用代理方法时,通过反射调用目标方法,因此会引入一定的性能开销。但对于接口代理,JDK动态代理是唯一的选择。

 CGLIB动态代理直接调用目标方法,省去了反射的开销,因此在性能上通常比JDK动态代理略快。但是对于final类、private方法和static方法等无法代理的情况,CGLIB无法生成代理类。

总结

  本篇文章带你了解cglib动态代理的外表,它的内部逻辑是如何实现的呢,还遗留了两个问题,博主会为cglib动态代理做一个系列的博客。

  • 问题1:代理类执行方法是如何被拦截的
  • 问题2:FastClass机制如何实现
相关文章
|
2月前
|
存储 C++ 容器
C++入门指南:string类文档详细解析(非常经典,建议收藏)
C++入门指南:string类文档详细解析(非常经典,建议收藏)
42 0
|
2月前
|
XML 存储 Java
Spring重要类解析
Spring重要类解析
21 0
|
2月前
|
Python
区域代理分红商城系统开发源码片段示例规则解析
level = Column(Integer, default=1) # 代理等级,例如:1代表普通用户,2代表初级代理,3代表高级代理等 parent_id = Column(Integer, ForeignKey('user.id')) # 上级代理ID 【更全面的开发源码搭建可V or TG我昵称】 parent = relationship("User", remote_side=[id]) # 上级代理对象
|
2月前
|
机器学习/深度学习 算法
【数学建模竞赛】评价类赛题常用算法解析
【数学建模竞赛】评价类赛题常用算法解析
33 0
|
12天前
|
XML JSON 关系型数据库
Pandas一键解析代理IP与代理IP池的维护
Pandas一键解析代理IP与代理IP池的维护
|
18天前
|
Java 数据库 Spring
切面编程的艺术:Spring动态代理解析与实战
切面编程的艺术:Spring动态代理解析与实战
27 0
切面编程的艺术:Spring动态代理解析与实战
|
18天前
|
Java
Java 15 神秘登场:隐藏类解析未知领域
Java 15 神秘登场:隐藏类解析未知领域
18 0
|
2月前
|
存储 程序员 编译器
【C++ 模板类与虚函数】解析C++中的多态与泛型
【C++ 模板类与虚函数】解析C++中的多态与泛型
46 0
|
2月前
|
Python
Python类与对象:深入解析与应用
本文介绍了Python中的核心概念——类和对象,以及它们在面向对象编程中的应用。类是用户定义的类型,描述具有相同属性和行为的对象集合;对象是类的实例,具备类的属性和方法。文章通过示例讲解了如何定义类、创建及使用对象,包括`__init__`方法、属性访问和方法调用。此外,还阐述了类的继承,允许子类继承父类的属性和方法并进行扩展。掌握这些概念有助于提升Python编程的效率和灵活性。
|
2月前
|
存储 安全 程序员
【C++ 包装器类 智能指针】完全教程:std::unique_ptr、std::shared_ptr、std::weak_ptr的用法解析与优化 — 初学者至进阶指南
【C++ 包装器类 智能指针】完全教程:std::unique_ptr、std::shared_ptr、std::weak_ptr的用法解析与优化 — 初学者至进阶指南
71 0

推荐镜像

更多