首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >@Autowired注解你真的会用吗?Spring官方有话说

@Autowired注解你真的会用吗?Spring官方有话说

作者头像
JavaEdge
修改2025-10-09 14:36:28
修改2025-10-09 14:36:28
2.2K0
举报
文章被收录于专栏:JavaEdgeJavaEdge

本文已收录在Github关注我,紧跟本系列专栏文章,咱们下篇再续!

  • 🚀 魔都架构师 | 全网30W技术追随者
  • 🔧 大厂分布式系统/数据中台实战专家
  • 🏆 主导交易系统百万级流量调优 & 车联网平台架构
  • 🧠 AIGC应用开发先行者 | 区块链落地实践者
  • 🌍 以技术驱动创新,我们的征途是改变世界!
  • 👉 实战干货:编程严选网

0 问题背景

用@Autowired时,发现IDEA报warning:

点击那三小点点:

再继续点:

Spring Team recommends "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies".

和阿里编码规范推荐似的,Spring团队推荐又来了:总是在你的bean中使用构造函数建立依赖注入。总是使用断言强制依赖”。

直接alt+enter写成这样子

代码语言:java
复制
public final StuMapper stuMapper;

public StuServiceImpl(StuMapper stuMapper) {
    this.stuMapper = stuMapper;
}

为啥这就不警告了?@Autowired可对成员变量、方法以及构造方法三种方式操作。

成员变量和构造方法设置又有啥区别?@Autowired注入bean,相当于在配置文件中配置bean,且使用setter注入。而对构造方法,就相当于用构造函数进行依赖注入吧。莫非是这两种注入方法的不同???

1 @Autowired和构造方法执行顺序差异

看一段代码,能运行成功吗?

代码语言:java
复制
@Autowired
private User user;
private String school;

public UserAccountServiceImpl(){
    this.school = user.getSchool();
}

不能。因为Java类会先执行构造方法,再给@Autowired的user注入值。

Java变量的初始化顺序:静态变量或静态语句块–>实例变量或初始化语句块–>构造方法–>@Autowired

因此执行构造方法时报错:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name '...' defined in file ....class: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate ...: Constructor threw exception; nested exception is java.lang.NullPointerException

创建Bean时出错,出错原因是实例化bean失败,因为bean时构造方法出错,在构造方法里抛NPE。

2 解决方案

通过构造方法注入

代码语言:java
复制
private User user;
private String school;

@Autowired
public UserAccountServiceImpl(User user) {
    this.user = user;
    this.school = user.getSchool();
}

使用构造方法注入,可明确成员变量的加载顺序。

3 为啥加final?

spring配置的bean的scope默认singleton,即启动后一直有。设置bean scope为prototype来声明该对象为动态创建。但若你的service本身是singleton,注入只执行一次。@Autowired本身就是单例模式,只会在程序启动时执行一次,即使不定义final也不会初始化第二次,所以这个final没意义吧。可能是为防止,在程序运行时,又执行一遍构造函数。

或者更易让人理解的,加上final只会在程序启动的时候初始化一次,且在程序运行的时候不会再改变。

FAQ

Q:构造方法上的@Autowired是否可省略,构造方法本身就可注入吧,加这注解的目的是啥?

A:Spring4.x新增特性:若类只提供一个带参构造方法,则无需对其内部的属性写@Autowired,Spring自动为你注入属性。

若调用了有参构造,执行了注入。若没调用有参构造,就得加@Autowired注入,可避免没有调用构造方法导致的空指针。

参考:

  • @Autowired和构造方法执行的顺序解析
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/04/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0 问题背景
  • 1 @Autowired和构造方法执行顺序差异
  • 2 解决方案
  • 3 为啥加final?
  • FAQ
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档