千家信息网

Spring和IDEA为什么都不推荐使用@Autowired注解

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,今天小编给大家分享一下Spring和IDEA为什么都不推荐使用@Autowired注解的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读
千家信息网最后更新 2026年10月31日Spring和IDEA为什么都不推荐使用@Autowired注解

今天小编给大家分享一下Spring和IDEA为什么都不推荐使用@Autowired注解的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

    Spring为什么不推荐使用@Autowired 注解

    背景

    做开发的同学可能都会发现, idea 在我们经常使用的@Autowired 注解上添加了警告
    警告内容是: Field injection is not recommended, 译为: 不推荐使用属性注入

    我们点击右侧三个小点查看描述, 可以看到信息如下图

    原因详情描述: Inspection info: Spring Team recommends: "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies".
    译为: Spring 团队建议: 始终在您的 bean 中使用基于构造函数的依赖注入。始终对强制依赖项使用断言

    原因

    为什么 Spring 建议我们在Bean中使用构造注入呢?
    想要回答这个问题, 我们需要了解 Spring的依赖注入(DI)方式
    Spring常用的注入方式有: 简单类型注入, 集合类型注入, 域属性自动注入, 自动注入的类别, 空值注入, 构造注入
    可以简化为: 属性注入, 构造方法注入, set 方法注入

    下面, 来用代码展示下三种方式注入

    属性注入
    可以看到, 我们开发最常用的就是属性注入

    @RestControllerpublic class AppointmentNumberConfigurationController {    @Autowired    private AppointmentNumberConfigurationService numberConfigurationService;}

    set 方法注入
    set 方法注入也会用到@Autowired注解,但使用方式与属性注入有所不同,
    属性注入是用在成员变量上,而set 方法的时候,是用在成员变量的Setter函数上。

    @RestControllerpublic class AppointmentNumberConfigurationController {    private AppointmentNumberConfigurationService numberConfigurationService;    @Autowired    public void setNumberConfigurationService(AppointmentNumberConfigurationService numberConfigurationService) {        this.numberConfigurationService = numberConfigurationService;}

    构造方法注入
    Constructor Injection是构造器注入,是我们最为推荐的一种使用方式。
    但是, 每次注入都按照这样的流程去构造注入的话, 会显得比较麻烦.
    至于如何去简化这一步骤, 我们可以继续往下看.

    @RestControllerpublic class AppointmentNumberConfigurationController {    final AppointmentNumberConfigurationService numberConfigurationService;        public AppointmentNumberConfigurationController(AppointmentNumberConfigurationService numberConfigurationService) {        this.numberConfigurationService = numberConfigurationService;    }    }

    三种方式对比如下

    使用属性注入可能会出现的问题

    基于属性注入的方式, 违背单一职责原则
    因为现在的业务一般都会使用很多依赖, 但拥有太多的依赖通常意味着承担更多的责任,而这显然违背了单一职责原则.
    并且类和依赖容器强耦合,不能在容器外使用。
    基于属性注入的方式, 容易导致Spring 初始化失败
    因为现在在Spring特别是Spring Boot使用中, 经常会因为初始化的时候, 由于属性在被注入前就引用而导致npe(空指针错误),
    进而导致容器初始化失败(类似下面代码块). Java 在初始化一个类时,
    是按照 静态变量或静态语句块 –> 实例变量或初始化语句块 –> 构造方法 -> @Autowired 的顺序。
    所以在执行这个类的构造方法时,person 对象尚未被注入,它的值还是 null。
    通过@Autowired 注入, 又因为是 ByType 注入, 因此有可能会出现两个相同的类型bean
    如下代码快, 就会产生两个相同的Bean, 进而导致Spring 装配失败
    //2. 基于属性注入的方式, 容易导致Spring 初始化失败@Autowiredprivate Person person;private String company;public UserServiceImpl(){    this.company = person.getCompany();}//3. 通过@Autowired 注入, 又因为是 ByType 注入, 因此有可能会出现两个相同的类型beanpublic interface IUser {    void say();}@Servicepublic class User1 implements IUser{    @Override    public void say() {    }}@Servicepublic class User2 implements IUser{    @Override    public void say() {    }}@Servicepublic class UserService {    @Autowired    private IUser user;}

    解决

    如果一定要使用属性注入, 可以使用 @Resource 代替 @Autowired 注解
    @Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。
    如果我们想使用按照名称byName来装配,可以结合@Qualifier注解一起使用。

    如果可能的话, 尽量使用构造注入
    Lombok提供了一个注解@RequiredArgsConstructor, 可以方便我们快速进行构造注入, 例如:

    @RestController@RequiredArgsConstructorpublic class AppointmentNumberConfigurationController {        final AppointmentNumberConfigurationService numberConfigurationService;    }

    同时需要注意:

    使用@RequiredArgsConstructor注解需要导入Lombok 包 或者安装lombok 插件

            org.projectlombok      lombok      1.18.16  

    必须声明的变量为final

    根据构造器注入的,相当于当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,
    其中每个参数代表一个对其他类的依赖。基于构造方法为属性赋值,容器通过调用类的构造方法将其进行依赖注入

    思考

    为什么推荐使用@Resource,不推荐使用@Autowired

    通过对问题1 的梳理, 我们可以知道.
    因为@Autowired 注解在Bean 注入的时候是基于ByType, 因此会由于注入两个相同类型的Bean导致装配失败

    @Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。
    如果我们想使用按照名称byName来装配,可以结合@Qualifier注解一起使用。

    @Resource装配顺序:
    ①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
    ②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
    ③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
    ④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

    因此, 如果一定要使用属性注入, 可以使用 @Resource 代替 @Autowired 注解

    @Autowired, @Qualifier, @Resource, 三者有何区别

    • @Autowired: 通过byType 方式进行装配, 找不到或是找到多个,都会抛出异常。

    • @Qualifier: 如果想让@Autowired 注入的Bean进行 byName装配, 可以使用 @Qualifier 进行指定

    • @Resource :作用相当于@Autowired,只不过 @Resource 默认按照byName方式装配, 如果没有匹配, 则退回到 byType 方式进行装配

    以上就是"Spring和IDEA为什么都不推荐使用@Autowired注解"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。

    属性 装配 方式 注解 方法 推荐 类型 变量 容器 相同 两个 函数 知识 篇文章 上下 上下文 代码 作用 内容 只不过 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 伟宏互联网科技 互联网科技公司税收优惠 互联网下的科技发展 互联网科技与金融科技 狮子座互联网科技 九亚互联网科技 睿民互联网科技 亿人帮互联网科技 宁波青枫互联网科技有限公司 欧洲十大科技互联网公司 来此购互联网科技有限公司 河南猎农互联网科技有限公司 本届互联网博览会上的黑科技 迪庆互联网科技招生 合肥互联网科技公司公章图片 工业互联网科技成果转化 九思连强互联网电子科技有限公司 抖集互联网科技技术咨询 互联网对科技影响 恒生互联网科技趋势 合肥互联网科技公司 互联网营销推广黑科技 四川互联网展示科技馆设计 上海创道互联网络科技有限公司 上海同邻互联网科技有限公司规模 云鲸互联网络科技有限公司 互联网高科技行业有哪些企业 互联网科技职业技能培训学校 科技互联网专业务虚会材料 上海旺乐尼互联网科技有限公司
    0