Spring Boot 2.0 改 CGLIB 后,接口实现是否有影响

3 个真正有影响的场景(老哥 7+ 年必看

场景 1:直接 new 出来的对象(不走 Spring 容器
复制代码
@Servicepublic class OrderService {        public void process() {        // ❌ 这个对象不是代理,没有事务、没有拦截        OrderService self = new OrderService();        self.process();  // 事务不生效    }}

这个问题不管 JDK 还是 CGLIB 都有(new 出来的对象不走容器)。

**但 CGLIB 升级后,这个坑更容易踩

  • JDK 代理时,代理对象实现接口,开发期容易发现(类型不对)
  • CGLIB 代理时,代理对象继承实现类new 出来的对象看着类型对 (都是 OrderService),但实际是裸对象
场景 2:强制类型转换到具体类(CGLIB 升级的经典坑
复制代码
// ❌ 错误写法:JDK 代理不会报错,CGLIB 代理会 ClassCastExceptionpublic class AppConfig {        @Autowired    private OrderService orderService;  // 注入的是代理对象        public void test() {        OrderServiceImpl impl = (OrderServiceImpl) orderService;  // ❌        // JDK 代理:ClassCastException(代理不是实现类子类)        // CGLIB 代理:✅ 成功(代理是实现类子类)    }}

等等,CGLIB 代理能转成功?这是好事还是坏事?

这是坏事因为 CGLIB 代理对象虽然继承 OrderServiceImpl,但重写了方法**(加事务拦截)**:

  • ((OrderServiceImpl) proxy).createOrder()走代理(有事务)
  • 表面上看着是 OrderServiceImpl,实际行为是代理的

这会导致 2 个问题:

1.绕过代理 (如果用 super.createOrder() 调用)

2.类型混乱(调试时看到是 OrderServiceImpl,实际行为是代理)

场景 3:Proxy.newProxyInstance 自定义代理(项目里要警惕
复制代码
public class CustomProxyFactory {        public static <T> T createProxy(Class<T> interfaceClass, T target) {        return (T) Proxy.newProxyInstance(  // ✅ JDK 代理            interfaceClass.getClassLoader(),            new Class<?>[] { interfaceClass },            new InvocationHandler() {                @Override                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                    System.out.println("Before: " + method.getName());                    Object result = method.invoke(target, args);                    System.out.println("After: " + method.getName());                    return result;                }            }        );    }}

CGLIB 升级影响:

  • 项目里自定义的 JDK 代理代码仍然能用
  • 但和 Spring 管理的 Bean(CGLIB 代理)混用时,行为可能不一致
追问 :Spring Boot 2.0 为什么要把默认改成 CGLIB?

"3 个原因

1.现代项目大多用 @Service/@Component很多类没有接口

2.JDK 代理必须有接口 ,CGLIB 不需要(更灵活

3.CGLIB 性能已经接近 JDK 代理(CGLIB 3+ 优化很多)

Spring Boot 2.0 把默认改成 CGLIB,避免项目里出现'有接口用 JDK、没接口用 CGLIB'的混乱。"

记忆口诀

"CGLIB 继承类又实现接口,99% 项目无影响"

"final 类/方法/static,CGLIB 全都代理不了"

"JDK 代理只能 public,CGLIB 能 private,但建议显式 public"

"Spring Boot 2.0 默认 CGLIB 智能切换,3 个真坑要知道"

一句话总结

"Spring Boot 2.0 改 CGLIB 后,接口实现基本无影响(CGLIB 既继承类又实现接口)。

3 个真正有影响的场景:

1.直接 new 出来的对象(不走容器)

2.强制类型转换(CGLIB 行为不同)

3.自定义 Proxy.newProxyInstance(混用问题)

相关推荐
guodingdingh38 分钟前
软件开发工作问题总结0718
java·开发语言·数据库
咖啡八杯2 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
优橙教育2 小时前
5G网优培训 vs Java开发:转行选哪个?
java·开发语言·5g
糖果店的幽灵3 小时前
【DeepAgents 从入门到精通】Context Management 上下文管理
java·人工智能·后端·spring·中间件·langgraph·deepagents
腻害兔4 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
SeaTunnel4 小时前
从 Python Script 地狱到标准化数据集成框架
大数据·开发语言·python·程序员·代码·seatunnel
碎光拾影5 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
Marst Code5 小时前
(python)2026Plotly 库评估:交互式可视化到底值不值得引入?
开发语言·python
Miao121316 小时前
微服务 API 测试实践:海外某民宿平台如何构建模式驱动测试基础设施
java·开发语言
腻害兔6 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:支付模块 yudao-module-pay,一个让产品经理都看懂的支付中台设计
java·前端·vue.js·产品经理·ai编程