Spring为什么需要CGLib(通俗易懂版)

简介: Spring动态代理CGLib

Spring 框架的核心框架之一是 AOP。允许在不修改原有代码的情况下,给程序添加一些“通用功能”,比如:
记录日志: 谁调用了哪个方法?花了多长时间?
事务管理: 开始一个数据库操作前自动开启事务,结束后自动提交或回滚。
安全检查: 执行方法前看看用户有没有权限。
性能监控: 统计方法执行时间。

Spring 实现 AOP 的主要方式是使用“代理”。
想象一下,你(业务对象)本来要亲自做一件事(比如调用 saveUser() 方法保存用户)。但 Spring 想在你做事 之前 或 之后 加点“调料”(比如开启/提交事务)。它不能直接修改你的代码,怎么办?
Spring 会找一个“替身”(代理对象)站在你前面。当别人想找你做事时,实际上先找到这个替身。这个替身会:
①先做“调料”的事情(比如开启事务)。
②然后再把你叫出来,让你真正做事(调用你真正的 saveUser() 方法)。
③等你做完事,替身可能再做点“收尾调料”(比如提交事务)。
④最后把结果告诉最初找你的人。

Spring 主要有两种造替身的方法:
①JDK 动态代理: 这是 Java 自带的本事。
怎么造? 它要求你必须有一个“行为规范”(接口)。比如你有一个 UserService 接口,里面定义了 saveUser() 方法,然后你有一个 UserServiceImpl 类实现了这个接口。
怎么工作? JDK 代理会创建一个新的对象,这个新对象也实现了 UserService 接口。当别人调用这个代理对象的 saveUser() 时,代理就能在调用真正 UserServiceImpl 的 saveUser() 前后加入“调料”了。
限制: 如果某个类没有实现任何接口,JDK 代理就没办法了!因为它造替身的前提是必须有个接口可以模仿。

②CGLib 动态代理: 这就是 Spring 所需要的方案。
怎么造? 它不需要接口!CGLib 使用了一种“黑科技”(操作字节码),它直接继承你要代理的那个类(比如 UserServiceImplWithoutInterface),然后生成这个类的一个子类作为替身。
怎么工作? 这个生成的子类(代理对象)重写了父类(原始类)的方法。当别人调用这个子类对象的 saveUser()(即使这个方法不是来自接口,而是原始类自己定义的)时,子类方法就能在调用父类真正的 saveUser() 前后加入“调料”了。
优点: 它不需要接口!能代理那些没有实现接口的普通类(POJO)。

Spring 为什么需要 CGLib?
现实世界不是只有接口: 很多遗留代码、第三方库的类或者开发者自己写的简单类,并没有实现接口。Spring 想要给这些类也加上 AOP 的魔法(事务、日志等),JDK 代理就无能为力了。
灵活性: Spring 希望尽可能广泛地支持各种类型的 Bean(Spring 管理的对象)。如果只依赖 JDK 代理,那么所有想被 AOP 增强的类都必须实现接口,这限制太大了,不符合 Spring 方便易用的哲学。
代理类本身的方法: JDK 代理只能代理接口定义的方法。如果一个类有自己的方法(不是接口方法),即使它有接口,JDK 代理也无法代理那些非接口方法。CGLib 通过继承则可以代理类中的几乎所有方法(除了 final 的)。

目录
相关文章
|
设计模式 安全 Java
深入理解Spring Boot AOP:CGLIB代理与JDK动态代理的完全指南
深入理解Spring Boot AOP:CGLIB代理与JDK动态代理的完全指南
3442 1
Spring5源码(27续)-cglib原理解析
Spring5源码(27续)-cglib原理解析
95 0
|
Java Linux iOS开发
Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
174 0
|
Java Maven Spring
Spring编译源代码解决spring-core缺少cglib和objenesis的jar包的办法
Spring编译源代码解决spring-core缺少cglib和objenesis的jar包的办法
137 0
|
Java Apache Spring
Spring BeanUtils 2、Cglib BeanCopier 3、Apache BeanUtils 4、Apache PropertyUtils 5、Dozer 那么,我们到底应该选择哪种工具类更加合适呢?为什么Java开发手册中提到禁止使用Apache BeanUtils呢
Spring BeanUtils 2、Cglib BeanCopier 3、Apache BeanUtils 4、Apache PropertyUtils 5、Dozer 那么,我们到底应该选择哪种工具类更加合适呢?为什么Java开发手册中提到禁止使用Apache BeanUtils呢
178 0
|
缓存 Java Spring
Spring AOP中CGLIB代理对象增强通知执行原理
Spring AOP中CGLIB代理对象增强通知执行原理
161 0
|
Java Spring
探究Java spring中jdk代理和cglib代理!
探究Java spring中jdk代理和cglib代理!
347 0
|
设计模式 Java 编译器
Spring AOP【AOP的基本实现与动态代理JDK Proxy 和 CGLIB区别】
Spring AOP【AOP的基本实现与动态代理JDK Proxy 和 CGLIB区别】
Spring AOP【AOP的基本实现与动态代理JDK Proxy 和 CGLIB区别】
|
Java Spring
Spring系列七:JDK 动态代理和 CGLIB 代理
​ 21.说说JDK 动态代理和 CGLIB 代理 ? Spring的AOP是通过动态代理来实现的,动态代理主要有两种方式JDK动态代理和Cglib动态代理,这两种动态代理的使用和原理有些不同。 JDK 动态代理 CgLib 动态代理 我们来看一个常见的小场景,客服中转,解决用户问题: 用户向客服提问题 JDK动态代理实现: JDK动态代理类图 public interface ISolver {     void solve(); } public class Solver implements ISolver {     @Override     pu
422 0
Spring系列七:JDK 动态代理和 CGLIB 代理