@Lazy注解使用注意事项

说明:在使用@Autowired注解,自动装配某Bean时,为了避免循环依赖(即自己注入自己,或两个Bean之间互相注入),可使用@Lazy注解,使其不在项目启动的时候就注入Bean,而是在首次使用的时候再注入,即懒加载,可以解决循环依赖的问题。

本文介绍使用@Lazy可能会出现的空指针异常(NPE)。

场景

如下,在 AsyncServiceImpl 内调用本类的方法,自己注入了自己

java 复制代码
import com.hezy.mapper.UserMapper;
import com.hezy.pojo.UserDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

@Service
public class AsyncServiceImpl {

    @Autowired
    @Lazy
    private AsyncServiceImpl asyncService;

    @Autowired
    private UserMapper userMapper;

    public void insertDTO1(UserDTO userDTO) {
        asyncService.insert(userDTO);
    }

    private void insert(UserDTO userDTO) {
        userMapper.insertUser(userDTO);
    }
}

这种情况,如果不加 @Lazy 注解,启动项目,会报循环依赖错误

问题

启动项目,发现在这里发生了空指针异常

解决

排查下来是因为成员方法insert()为private修饰,换成public就行了,如下:

分析

推测可能与动态代理的方式有关,CGLIB动态代理要求被代理的类或方法不能被final修饰。

对于上述场景,除了修改成员方法的修饰符,把private改为public,还可以考虑不走代理,而直接调用成员方法,如下,都不需要注入自己。

java 复制代码
    @Autowired
    private UserMapper userMapper;

    public void insertDTO1(UserDTO userDTO) {
        insert(userDTO);
    }

    public void insert(UserDTO userDTO) {
        userMapper.insertUser(userDTO);
    }

大家可能有两个问题:


问:为什么要自己注入自己?直接调用成员方法不就行了?

答:因为要考虑到事务,如果用声明式注解,直接调用成员方法,事务会失效。上述代码没有事务问题,故可以直接调用成员方法。


问:为什么方法要用private修饰?直接用public多省事。

答:因为规范,成员方法如果只在本类中使用,须用private修饰。


相关推荐
野生的码农8 小时前
码农的妇产科实习记录
android·java·人工智能
盖世英雄酱581368 小时前
Java 组长年终总结:靠 AI 提效 50%,25 年搞副业只赚 4k?
后端·程序员·trae
毕设源码-赖学姐9 小时前
【开题答辩全过程】以 高校人才培养方案管理系统的设计与实现为例,包含答辩的问题和答案
java
+VX:Fegn08959 小时前
计算机毕业设计|基于springboot + vue在线音乐播放系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
一起努力啊~9 小时前
算法刷题-二分查找
java·数据结构·算法
小途软件9 小时前
高校宿舍访客预约管理平台开发
java·人工智能·pytorch·python·深度学习·语言模型
J_liaty9 小时前
Java版本演进:从JDK 8到JDK 21的特性革命与对比分析
java·开发语言·jdk
code bean9 小时前
Flask图片服务在不同网络接口下的路径解析问题及解决方案
后端·python·flask
+VX:Fegn08959 小时前
计算机毕业设计|基于springboot + vue律师咨询系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
努力的小郑9 小时前
2025年度总结:当我在 Cursor 里敲下 Tab 的那一刻,我知道时代变了
前端·后端·ai编程