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

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

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

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

相关推荐
dadaobusi5 小时前
学习:RV lkvm SBI
java·学习·spring
HEJOO97 小时前
深入理解 Java volatile 关键字:原理、用法与常见误区
java·开发语言·spring
曹牧7 小时前
Java:no content to map due to end of input
java·开发语言
阿维的博客日记7 小时前
Example 类全场景实战指南
java·mybatis
两点王爷7 小时前
SpringBoot 项目集成 GeoServer 源码,实现地图服务发布
java·spring boot·后端
Javatutouhouduan8 小时前
Java如何速通性能优化难题?
java·java面试·jvm调优·后端开发·java程序员·java八股文·java性能优化
lemon_sjdk8 小时前
DOM 节点
java·前端·javascript
leoZ2318 小时前
2026-09-09-springboot-cloud-deploy-pitfalls
java·前端·javascript·vue.js·人工智能·spring boot·后端
驭渊的小故事9 小时前
多线程02
java·开发语言·jvm
随遇而安zx9 小时前
【多线程】---实战:CompletableFuture编排
java·多线程·并发