Spring的配置类分成Full和Lite两种模式。
官方定义为:在没有标注 @Configuration 的类里面有 @Bean 方法就称为Lite模式的配置类。
透过源码再看这个定义是不完全正确的,而应该是如下case均认为是Lite模式的配置类。
- 类上没有标注 @Configuration,但有 @Component、@ComponentScan、@Import、@ImportResource;
- 类上没有注解,但类内方法存在 @Bean注解。
在Spring 5.2之后,新增了一种case也算作Lite模式:
标注有 @Configuration(proxyBeanMethods = false) 的类,注意:此值默认是true。
自Spring 5.2(对应Spring Boot 2.2.0)开始,内置的几乎所有的 @Configuration配置类都被修改为了 @Configuration(proxyBeanMethods = false),目的是:降低启动时间,为Cloud Native做准备。
两个模式使用场景
配置类组件之间无依赖关系用 Lite 模式,加速容器启动过程,减少判断。创建新组建用lite,因为容器里面没有,不需要检查
配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,可以快速获取到bean,减少新生成实例的消耗,减少 jvm 垃圾回收,用 Full 模式。
在Lite模式下
- 配置类本身不会被CGLIB增强,放进IoC容器内的就是配置类本身;
- 配置类内部不能通过方法调用来处理依赖,否则每次生成的都是一个新实例而并非IoC容器内的单例
- 配置类就是一普通类嘛,所以内部的 @Bean方法可以使用private/final等进行修饰
在Full模式下
- 配置类会被CGLIB增强(生成代理对象),放进IoC容器内的是代理对象;
- 该模式下,配置类内部可以通过方法调用来处理依赖,并且能够保证是同一个实例,都指向IoC内的那个单例;
- 该模式下,@Bean方法不能被private/final等进行修饰(因为方法需要被重写,所以不能私有和final。defualt/protected/public都可以哦)
从上面的介绍可以看出来,Lite模式很大程度上是为了减少启动开销,提升程序的启动速度。所以如果你对程序的启动速度很敏感,就使用Lite模式,但是一定要记住此时的配置类已经不是经过Cglib增强过的类了。