SpringBoot 中给 @Autowired 搭配 @Lazy的使用

 更新时间:2026年03月17日 11:03:14   作者:J2虾虾  
在SpringBoot中,给@Autowired搭配@Lazy可以实现Bean的懒加载,但需要注意初始化异常延迟暴露、循环依赖场景的影响、性能与资源问题以及与作用域的兼容问题,本文介绍SpringBoot中给@Autowired搭配 @Lazy的使用,感兴趣的朋友跟随小编一起看看吧

在 SpringBoot 中给 @Autowired 搭配 @Lazy 使用是合法且常见的做法,但并非完全没有需要注意的问题,核心是要理解 @Lazy 的作用机制以及它可能带来的影响。

一、先理解核心概念

@Lazy 的核心作用是:将 Bean 的初始化时机从 Spring 容器启动时(饿汉式)推迟到该 Bean 第一次被使用时(懒汉式)。给 @Autowired@Lazy 有两种常见场景:

  1. 直接标注在 @Autowired 字段 / 方法上:延迟注入的这个 Bean 本身的初始化
  2. 标注在被注入的 Bean 类上:全局延迟该 Bean 的初始化

二、可能遇到的问题及注意事项

1. 初始化异常延迟暴露

这是最常见的问题:

  • 正常情况:非懒加载的 Bean 在容器启动时初始化,若存在依赖缺失、配置错误等问题,会直接报错,能快速发现问题。
  • 加 @Lazy 后:Bean 初始化推迟到第一次使用时,容器启动时不会报错,但在运行时第一次调用该 Bean 时才抛出异常(比如 NullPointerExceptionNoSuchBeanDefinitionException),可能导致线上故障。

示例

@Service
public class OrderService {
    // 延迟注入 UserService
    @Lazy
    @Autowired
    private UserService userService;
    public void processOrder() {
        // 第一次调用时才初始化 userService,若 userService 有初始化异常,此时才会报错
        userService.validateUser();
    }
}

2. 循环依赖场景的影响

Spring 默认能解决单例 Bean 的循环依赖,但 @Lazy 会改变循环依赖的处理逻辑:

  • 不加 @Lazy:Spring 通过三级缓存提前暴露 Bean 的早期引用解决循环依赖。
  • @Lazy:会直接返回一个代理对象(而非早期引用),虽然能解决更复杂的循环依赖,但如果对代理对象的类型敏感(比如强转),可能抛出 ClassCastException

反例(可能报错)

@Service
public class AService {
    @Lazy
    @Autowired
    private BService bService;
    public void test() {
        // 错误:bService 是代理对象,强转可能失败
        BServiceImpl b = (BServiceImpl) bService; 
    }
}
@Service
public class BService {
    @Autowired
    private AService aService;
}

3. 性能与资源问题

  • 首次调用耗时增加:第一次使用 Bean 时需要完成初始化(实例化、依赖注入、初始化方法执行),可能导致首次请求响应变慢(比如接口首次调用超时)。
  • 资源占用延迟:若 Bean 初始化需要占用大量资源(如连接数据库、加载缓存),延迟初始化会把资源占用的时机从启动时转移到运行时,可能影响服务运行时的资源分配。

4. 与作用域的兼容问题

@Lazy原型(Prototype)Bean 无效:原型 Bean 本身就是每次获取时新建,不存在 “延迟初始化” 的概念;若给请求作用域(Request)、会话作用域(Session)的 Bean 加 @Lazy,需要确保在对应的作用域上下文(如 Web 请求中)使用,否则可能抛出 ScopeNotActiveException

三、正确使用 @Lazy 的场景(避坑建议)

  1. 解决循环依赖:这是 @Lazy 最核心的合法用途,优先用它解决循环依赖,而非重构代码(短期方案)。
  2. 优化启动速度:对初始化耗时的 Bean(如大数据量缓存加载),延迟初始化能加快 Spring 容器启动速度。
  3. 按需加载 Bean:某些 Bean 仅在特定场景下使用(如定时任务、管理接口),延迟初始化可节省启动资源。

四、避坑最佳实践

  1. 核心业务 Bean 避免 @Lazy:核心流程的 Bean 建议饿汉式初始化,确保启动时暴露所有问题。
  2. 配合异常监控:若必须用 @Lazy,在首次调用处增加异常捕获和日志,便于定位问题。
  3. 测试覆盖:对懒加载的 Bean,编写专门的测试用例,主动触发初始化,避免线上首次调用报错。
  4. 替代方案优先:能通过重构代码(如引入中间层、拆分服务)解决循环依赖的,优先重构,而非依赖 @Lazy

到此这篇关于SpringBoot 中给 @Autowired 搭配 @Lazy的文章就介绍到这了,更多相关SpringBoot @Autowired 搭配 @Lazy内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Bean的实例化之属性注入源码剖析过程

    Spring Bean的实例化之属性注入源码剖析过程

    本篇文章主要就是分析Spring源码剖析-Bean的实例化-属性注入的相关知识,通过本文学习AbstractAutowireCapableBeanFactory#populateBean 方法的主要功能就是属性填充,感兴趣的朋友跟随小编一起看看吧
    2021-06-06
  • 详解JavaSE实现IoC

    详解JavaSE实现IoC

    简单地说,IoC 是反转控制,类似于好莱坞原则,主要有依赖查找和依赖注入实现。依赖查找是主动或手动的依赖查找方式,通常需要依赖容器或标准API实现。 而依赖注入则是手动或自动依赖绑定的方式,无需依赖特定的容器和API。本文将详细介绍JavaSE实现IoC。
    2021-06-06
  • Spring Boot 2.0快速构建服务组件全步骤

    Spring Boot 2.0快速构建服务组件全步骤

    这篇文章主要给大家介绍了关于Spring Boot 2.0快速构建服务组件的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot 2.0具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • java获取当前时间和前一天日期(实现代码)

    java获取当前时间和前一天日期(实现代码)

    java获取当前时间和前一天日期的实现代码。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • Java数据结构之链表相关知识总结

    Java数据结构之链表相关知识总结

    今天给大家带来关于Java数据结构的相关知识,文章围绕Java链表展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • springboot项目中mapper.xml文件找不到的三种解决方案

    springboot项目中mapper.xml文件找不到的三种解决方案

    这篇文章主要介绍了springboot项目中mapper.xml文件找不到的三种解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 基于idea把springboot项目部署到docker

    基于idea把springboot项目部署到docker

    这篇文章主要介绍了基于idea把springboot项目部署到docker,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Spring Boot中使用Spring-Retry重试框架的实现

    Spring Boot中使用Spring-Retry重试框架的实现

    本文主要介绍了Spring Boot中使用Spring-Retry重试框架的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • 解决遇到Cannot resolve ch.qos.logback:logback-classic:1.2.3错误的问题

    解决遇到Cannot resolve ch.qos.logback:logback-classic:

    当使用Maven配置项目依赖时,可能会遇到无法解析特定版本的错误,例如,logback-classic版本1.2.3可能无法在配置的仓库中找到,解决方法包括检查仓库是否包含所需版本,或更新到其他可用版本,可通过Maven官网搜索并找到适用的版本,替换依赖配置中的版本信息
    2024-09-09
  • SpringBoot+Docker+Graylog 如何让错误自动报警

    SpringBoot+Docker+Graylog 如何让错误自动报警

    SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK/Graylog实现集中监控与错误报警,本文给大家介绍SpringBoot+Docker+Graylog 如何让错误自动报警,感兴趣的朋友一起看看吧
    2025-07-07

最新评论