Spring中的Full模式和Lite模式,90%的开发都没搞明白

📅 2026/7/14 20:18:24 👁️ 阅读次数 📝 编程学习
Spring中的Full模式和Lite模式,90%的开发都没搞明白


来自:

推荐一个程序员编程资料站:

http://cxyroad.com

副业赚钱专栏:https://xbt100.top

2024年IDEA最新激活方法

后台回复:激活码

CSDN免登录复制代码插件下载:

CSDN复制插件

以下是正文。


Spring中的Full模式和Lite模式,90%的开发都没搞明白

很多人天天写Spring,但如果你问一句:

@Configuration 为什么还能分 Full 模式和 Lite 模式?

不少人会直接愣住。

因为大多数人只知道 @Configuration 是配置类,却不知道它背后其实隐藏着两套运行机制。

而这两种模式,直接影响:

  • Bean 会不会重复创建

  • Spring 是否使用 CGLIB 动态代理

  • 启动速度快不快

  • 配置类性能高不高

  • 微服务项目该怎么优化

今天这篇文章,小路就带你彻底搞懂 Spring 的 Full 模式 和 Lite 模式。

01 | @Configuration其实有两种运行方式

先看最普通的配置类:

@Configuration public class MyConfig { }

默认情况下,它属于 Full 模式。

而如果这样写:

@Configuration(proxyBeanMethods = false) public class MyConfig { }

那么它就变成了 Lite 模式。

很多人第一次看到 proxyBeanMethods 这个参数时,根本不知道它是干什么的。

实际上,它决定了:

Spring 是否对配置类进行 CGLIB 增强。

这也是 Full 和 Lite 最核心的区别。

02 | Full模式到底做了什么

默认情况下:

@Configuration

等价于:

@Configuration(proxyBeanMethods = true)

也就是说:

Spring 会通过 CGLIB 动态生成一个代理子类。

很多人不知道,真正放进 Spring 容器里的,其实已经不是你写的那个原始配置类了。

而是:

MyConfig$$EnhancerBySpringCGLIB

Spring 会把你的配置类偷偷代理掉。

为什么要这么干?

核心目的就一个:

保证@Bean方法返回的对象永远是单例。

举个例子。

@Configuration public class AppConfig { @Bean public UserService userService() { return new UserService(orderService()); } @Bean public OrderService orderService() { return new OrderService(); } }

这里有个关键点:

userService() 内部直接调用了 orderService()。

正常Java逻辑下:

orderService()

就是普通方法调用。

意味着:

每调用一次都会 new 一个新对象。

但Spring不允许这样。

因为:

@Bean 默认是单例。

于是 Spring 的 CGLIB 代理就登场了。

它会拦截:

orderService()

然后先去容器里检查:

有没有已经创建好的 Bean。

如果有:

直接返回容器里的对象。

而不是重新执行方法。

所以最终:

整个系统里只有一个 OrderService。

这就是 Full 模式最大的意义。

03 | Lite模式为什么越来越流行

再看 Lite 模式:

@Configuration(proxyBeanMethods = false)

这时候 Spring 不会再创建 CGLIB 代理。

@Bean 方法也不会被拦截。

意味着:

orderService()

就是一次普通Java调用。

调用一次:

创建一次对象。

这时候如果还存在配置类内部调用:

userService(orderService())

那么:

OrderService 就可能被创建多次。

这也是 Lite 模式最大的风险。

但问题来了。

既然有风险。

为什么现在越来越多人开始用 Lite 模式?

因为:

它真的快。

尤其是在微服务时代。

很多项目:

  • Bean 数量巨大

  • 配置类特别多

  • Spring Boot 自动配置越来越复杂

如果每个配置类都做 CGLIB 增强:

启动开销会明显增加。

而 Lite 模式直接省掉代理生成过程。

Spring 启动速度会更快。

内存占用也会更低。

所以现在很多官方自动配置:

都开始大量使用:

proxyBeanMethods = false

尤其 Spring Boot 2.2 以后特别明显。

04 | 为什么Spring Boot官方开始偏向Lite模式

Spring 官方后来发现:

大多数配置类,其实根本不需要 Bean 方法互相调用。

很多配置类只是:

@Bean public A a() @Bean public B b()

互相之间完全没关系。

这种情况下:

开启 CGLIB 代理纯属浪费。

于是 Spring Boot 官方开始大量优化:

能不用 Full 模式,就尽量不用。

因为对于现代微服务项目来说:

启动速度越来越重要。

容器化部署。

K8S弹性扩缩容。

Serverless冷启动。

都要求应用尽可能轻。

这也是为什么现在很多源码里你会看到:

@Configuration(proxyBeanMethods = false)

甚至有些自动配置类:

已经明确建议关闭代理。

05 | Full模式和Lite模式到底该怎么选

很多人看到这里开始纠结:

那以后到底该用哪个?

其实原则非常简单。

如果配置类内部:

存在@Bean之间互相调用。

比如:

a() 调用了 b()

那就必须使用 Full 模式。

否则可能出现:

Bean 被重复创建。

单例失效。

依赖错乱。

但如果:

@Bean 方法之间完全独立。

没有互相调用。

那么直接使用 Lite 模式更合适。

因为:

  • 启动更快

  • 内存更省

  • 少了CGLIB代理

  • 更适合微服务

现在很多高性能Spring项目:

都会主动关闭:

proxyBeanMethods

这是近几年Spring生态一个非常明显的趋势。

06 | 一个很多人踩过的大坑

很多开发切到 Lite 模式后。

会突然发现:

单例失效了。

例如:

@Bean public A a() { return new A(b()); } @Bean public B b() { return new B(); }

在 Lite 模式下:

b()

不会从容器获取。

而是真正执行方法。

于是:

new B()

被执行多次。

最终:

A 里的 B

和容器里的 B

根本不是同一个对象。

这个坑很多人线上都踩过。

所以记住一句话:

Lite 模式下。

@Bean 方法之间尽量不要直接调用。

正确做法应该是:

通过参数注入。

例如:

@Bean public A a(B b) { return new A(b); }

这样 Spring 会自动从容器里拿 Bean。

既不会重复创建。

又能安全使用 Lite 模式。

07 | 现在真正厉害的Spring开发,早就开始主动优化配置类了

以前很多人写 Spring:

根本不管配置类性能。

反正能跑就行。

但现在不一样了。

微服务越来越重。

自动配置越来越多。

启动时间已经变成核心指标。

尤其云原生时代:

启动慢。

就意味着:

扩容慢。

恢复慢。

成本更高。

所以现在很多大厂:

已经开始专门治理 Spring 配置类。

能 Lite 的绝不 Full。

能避免代理的绝不增强。

因为大型系统里:

几百个配置类叠加起来。

差距真的会越来越明显。

这也是为什么:

真正懂 Spring 底层的人。

看到一个:

@Configuration

第一反应不是配置类。

而是:

这里到底需不需要 CGLIB 代理。

<END>

推荐阅读:

副业赚钱推荐:让你的时间开始变现!

免费体验AI图片生成,就在 Image Generator Hub!

程序员在线工具站:cxytools.com 推荐一个自己写的工具站:https://cxytools.com,专为程序员设计,包括时间日期、 JSON处理、SQL格式化、随机字符串生成、UUID生成、文本Hash...等功能,提升开发效 率。 ⬇戳阅读原文直达! 朕已阅