Spring-Bean生命周期-构造器访问Autowired字段为null

Spring Bean 生命周期:为什么构造器里访问 @Autowired 字段是 null

Spring 依赖注入的坑很多,其中一个经典问题是"构造器里访问 @Autowired 字段拿到 null"。本文讲清楚 Bean 生命周期的执行顺序,以及正确的注入方式。

一、问题案例

一个新写的服务,启动就报 NullPointerException。排查后发现,代码在构造器里直接使用了 @Autowired 注入的字段:

java 复制代码
@Service
public class OrderService {

    @Autowired
    private UserService userService;   // 字段注入

    public OrderService() {
        userService.init();            // ❌ 构造器里使用,这行必炸
    }
}

userService 是 null。明明标了 @Autowired,为什么是 null?

二、原理:Bean 生命周期顺序

Spring 创建 Bean 的顺序是固定的:

复制代码
1. 实例化(调用构造器)        ← 此时字段全是 null
2. 依赖注入(@Autowired)    ← 字段在这一步才被赋值
3. @PostConstruct            ← 初始化回调
4. 交给容器使用

构造器在第 1 步执行,依赖注入在第 2 步。所以构造器执行时,字段还没被注入,全是 null。字段注入的本质是"先 new 出来,再回头填字段",必然存在这个时间差。

三、正确写法

方案一:构造器注入(推荐)

java 复制代码
@Service
public class OrderService {

    private final UserService userService;

    public OrderService(UserService userService) {   // ✅ 依赖作为构造参数
        this.userService = userService;
        userService.init();                          // ✅ 构造器里已可用
    }
}

依赖作为构造参数传入,构造器里天然可用,字段还能声明为 final

方案二:把初始化逻辑挪到 @PostConstruct

java 复制代码
@Autowired
private UserService userService;

@PostConstruct
public void init() {
    userService.init();   // ✅ @PostConstruct 时字段已注入
}

四、延伸:三个初始化回调的顺序

如果需要在 Bean 初始化时执行逻辑,有三个入口,执行顺序如下:

顺序 方式 时机
1 @PostConstruct 字段注入完成后
2 InitializingBean.afterPropertiesSet() @PostConstruct 之后
3 @Bean(initMethod = "xxx") afterPropertiesSet 之后

三者都在依赖注入之后执行,都能安全访问字段。唯独构造器不行。

五、总结

  • 构造器执行时,@Autowired 字段尚未注入,访问必为 null。
  • 推荐使用构造器注入 ,或把初始化逻辑放到 @PostConstruct
  • 三个初始化回调(@PostConstruct / afterPropertiesSet / initMethod)都在注入之后。

我是无羡(小剑),全栈偏后端的独立开发者。

作品集:无羡 · 独立开发者作品集

如果对你有帮助,欢迎点赞、收藏、关注。

相关推荐
子兮曰8 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!9 小时前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰9 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里9 小时前
java中的继承和多态的区别
java
小羊没烦恼!9 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
爱勇宝9 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕9 小时前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码9 小时前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖9 小时前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时10 小时前
01-06-A-JVM排查实战详解
java·jvm