大家好,我是锋哥。今天分享关于【SpringBoot为什么默认使用CGLIB?】面试题。希望对大家有帮助;
SpringBoot为什么默认使用CGLIB?
1000道 互联网大厂Java工程师 精选面试题-Java资源分享网
Spring Boot 默认使用 CGLIB(Code Generation Library)作为代理机制之一,主要是因为 CGLIB 在一些场景下相比于 JDK 动态代理具有更好的性能和灵活性,尤其在需要代理 类(而非接口)时。具体原因可以归纳为以下几点:
1. 无接口代理的需求
-
在 Spring 中,AOP(面向切面编程)使用代理模式来实现功能增强。Spring AOP 默认支持两种代理方式:
- JDK 动态代理:只能代理实现了接口的类。
- CGLIB 代理:可以代理普通的类,甚至没有实现任何接口的类。
-
在很多 Spring 应用中,尤其是使用了类而非接口的情况下,CGLIB 代理显得更为灵活。JDK 动态代理无法代理没有实现接口的类,而 CGLIB 能够通过继承原始类来实现代理,这使得 CGLIB 更适合那些没有接口的类。
2. 性能优势
- CGLIB 是基于字节码生成的,采用继承原理创建代理类。与 JDK 动态代理相比,CGLIB 生成的代理类没有接口方法的调用开销,因为它直接继承自原始类,通过重写方法来实现增强。
- 对于没有接口的类,CGLIB 可以提供相对更高的性能,因为不需要额外的接口调用。
3. Spring 默认的代理策略
- Spring 默认使用 CGLIB 代理的策略实际上是基于 代理目标类是否实现接口来决定的。如果目标类没有实现接口,Spring 会默认使用 CGLIB 代理;如果目标类实现了接口,Spring 则使用 JDK 动态代理。
- 因为 CGLIB 是通过生成子类的方式来实现代理的,能够直接对方法进行增强,而不依赖接口。所以当你没有为你的类定义接口时,Spring 会倾向于使用 CGLIB 来自动代理。
4. 更灵活的功能增强
- CGLIB 代理能够增强实例的所有方法,而不仅仅是接口方法。这使得 CGLIB 在不通过接口的情况下仍能提供灵活的切面功能增强(如事务管理、日志等)。
- 使用 CGLIB 代理,Spring 可以对类中的方法进行增强,而不要求每个方法都必须通过接口来定义,这对于开发者来说更为方便,尤其是在没有接口或者接口很不适合的场景下。
5. Spring AOP 和事务管理
- 在 Spring 的事务管理中,很多时候我们会对某些业务方法进行事务控制。若你的服务类没有接口,Spring 默认会使用 CGLIB 来生成代理对象,确保方法调用能够被事务管理器拦截和增强。
- 使用 CGLIB 代理后,事务等切面可以应用到类中的所有方法,而不仅仅局限于接口方法。
6. Spring Boot 和 Spring AOP
- 在 Spring Boot 中,自动配置以及 Spring AOP 会根据类的实现情况来选择适当的代理方式。如果目标类没有接口,Spring Boot 会默认使用 CGLIB 来进行代理,确保 AOP 和事务管理等功能能够正确应用。
总结:
Spring Boot 默认使用 CGLIB 的原因,主要是为了支持没有接口的类的代理,并提高灵活性和性能。在实际开发中,Spring 会根据目标类是否实现接口来选择合适的代理方式,如果没有接口,就会选择 CGLIB 作为默认的代理机制。这样,开发者可以更方便地使用 AOP 和事务管理等功能,而无需依赖接口。