SpringBoot项目如何进行预热?
Spring Boot 里做数据预热 / 缓存预热,我常用这几种方式:
- 监听 Spring 容器启动完成事件
监听 ContextRefreshedEvent 或 ApplicationReadyEvent ,
在容器完全启动、所有 Bean 初始化好之后,执行预热逻辑。
- 使用 Bean 初始化相关注解/接口
@PostConstruct :Bean 初始化之后执行
实现 InitializingBean 重写 afterPropertiesSet 方法
这些是在 Bean 创建完成时就执行,适合早一点加载基础数据。
- 使用 Spring Boot 专用启动扩展接口(最推荐)
ApplicationRunner
CommandLineRunner
它们会在 Spring Boot 应用完全启动成功、准备接收请求之前 执行,
是做数据预热、缓存预热最标准、最合适的方式。
@Lazy解决构造函数循环依赖
字段或 Setter 注入的循环依赖,Spring 靠三级缓存在初始化阶段提前暴露半成品对象来解决。但构造器注入在实例化阶段就需要依赖,此时三级缓存还没介入,所以默认解决不了。
我会在其中一个构造器参数上添加 @Lazy 注解。比如 A 和 B 构造器循环依赖,给 A 构造器里的 B 参数加 @Lazy ,Spring 不会立即创建 B,而是注入一个代理对象。这样 A 就能顺利完成实例化和初始化,放入单例池。当后续首次调用 B 的方法时,代理会触发真实 B 的创建,这时 B 再去依赖注入已经存在的 A,就打破了构造器的循环依赖。
Bean生命周期
- singleton(单例)
整个 Spring 容器 内唯一一份。
- prototype(原型)
每次获取都创建新对象。
- request
每次 HTTP 请求一个新 Bean。
- session
每个用户会话一个新 Bean。
- application
每个 Web 应用(ServletContext) 一个 Bean。
- websocket
每个 WebSocket 长连接一个 Bean。
实际上单例和application是差不多的,一般来说单例是Spring容器级别的,application是Web应用级别的,同一个Web应用一般表现一样,但一个应用有多个Spring容器的时候就单例会有多个,但是Application会有多个
多环境配置
Spring Boot 实现多环境配置,主要通过 Profile 机制来完成:
- 我们可以使用 @Profile 注解,标记在配置类或者 Bean 上,
用来指定这个 Bean 或配置在哪个环境下才会被创建、注入,比如 dev、test、prod。
- 同时,我们可以创建多个环境配置文件:
application-dev.yml
application-test.yml
application-prod.yml
- 然后在主配置文件 application.yml 里,通过
spring.profiles.active 来指定当前激活哪个环境。
- 启动项目时,Spring Boot 会根据激活的环境,
自动加载对应的配置文件,并且只注入对应环境的 Bean,
从而实现多环境的切换。