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)都在注入之后。

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

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

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

相关推荐
Pniubi11 分钟前
区分Java创建线程池、多线程
java·线程·线程池·多线程·并发
程序员梅雨17 分钟前
ZooKeeper面经总结
java·大数据·linux·分布式·后端·zookeeper·中间件
Yyyyyy~37 分钟前
【Java】多线程初阶
java
蜗牛互联网38 分钟前
Java 17 调用视觉 Responses API:JSON 约束与人工复核路由
java·人工智能·后端
SL_staff2 小时前
物模型三要素误用避坑指南:属性、事件、服务的正确建模逻辑
java
高频因子挖掘机2 小时前
股票分红送转后价格“断层”:前复权、后复权和不复权该怎么选?
后端·github·api
一条泥憨鱼2 小时前
【Redis | 黑马点评】短信登录功能 源码深度分析
java·redis·后端·session·黑马点评
威哥爱编程2 小时前
【AI全栈12-12】Spring Boot 3.x → 4.x 迁移实操:Jakarta 11、Jackson 3 与 AI 2.0
java·spring boot·后端
威哥爱编程2 小时前
【AI全栈12-11】Spring Boot 把 AI 接口真正上线扛量:限流 / 降级 / 可观测
java·spring boot·后端
小蒜学长2 小时前
基于SpringBoot+uni-app的闪洁家政系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·uni-app·家政服务