☰
一看看懂@Autowired 和 @Resource区别(附代码)
2026/10/3 7:26:38 网站建设 项目流程

❗️❗️❗️

看了一下大部分的文章都只讲了区别是byType和byName,具体什么是byType和byName却没有详尽的解释,文章末尾会具体的讲清楚这些区别。

目录

@Autowired 和 @Resource

一、@Autowired

二、@Resource

三、byType(按类型注入)

四、byName(按名称注入)

五、byName和byType放一起对比

六、表格对比

七、一句话总结

八、开发使用建议


@Autowired 和 @Resource

两者都是依赖注入注解,用来把 Spring 容器中的 Bean 注入到变量上,核心区别:

@Autowired是Spring 框架自带注解;

@Resource是Java 官方标准注解。

一、@Autowired

@Autowired private UserService userService;
  1. 所属包:org.springframework.beans.factory.annotation.Autowired,Spring 特有。
  2. 默认注入规则:按类型(byType)
    • Spring 去容器里找类型完全匹配的 Bean 注入。
    • 如果同类型有多个 Bean,会报错NoUniqueBeanDefinitionException。
      • 解决:搭配@Qualifier("beanName")指定 bean 名称。
      @Autowired @Qualifier("userServiceImpl1") private UserService userService;
  3. 默认要求 Bean 必须存在,找不到就抛异常; 可以设置required = false变成非必须:@Autowired(required = false)
  4. 支持位置:成员变量、setter 方法、构造方法

    Spring4.3+,构造方法上的@Autowired可以省略,只有一个构造器时自动注入。

二、@Resource

@Resource private UserService userService;
  1. 所属包:javax.annotation.Resource(jdk8)/jakarta.annotation.Resource(jdk9+),Java 规范,不是 Spring 专属。
  2. 注入顺序:先按名称 (byName),找不到再按类型 (byType)
    • 优先:拿变量名当作 bean 名字去容器查找;
    • 按名字找不到,退化成按类型 byType 注入。
    • 可以手动指定名字:@Resource(name = "userServiceImpl1")
  3. 没有 required 属性,找不到 Bean 直接报错。
  4. 支持位置:成员变量、setter 方法,不支持构造方法注入。

三、byType(按类型注入)

@Autowired默认 byType:根据变量的类型,去 Spring 容器里找这个类型的 Bean 对象,找到就赋值给变量。

❗️❗️❗️重点:看变量的类型,不是看变量名字。

例子

1. 接口 + 实现类

// 接口 public interface UserService { //.... } // 实现类1,交给Spring管理 @Service public class UserServiceImpl implements UserService { //.... }

Controller 里注入:

// 变量类型:UserService @Autowired private UserService userService;

✅ byType 执行过程:

  1. 看变量userService的类型:UserService
  2. Spring 去容器查找:有没有 Bean 是 UserService 类型(或者它的实现类)
  3. 找到UserServiceImpl这个 Bean,注入进来。

变量名字叫aaa也完全没问题!因为 byType不看名字

@Autowired private UserService aaa; // 照样正常注入,只看类型UserService

2. 同一个类型,容器里面有多个 Bean

通俗讲,如果这个接口有多个实现类:

@Service public class UserServiceImpl2 implements UserService { //.... }

现在容器里有两个 UserService 类型的 Bean:UserServiceImpl、UserServiceImpl2

@Autowired private UserService userService; //👉 Spring:找到了 2 个同类型 Bean,不知道注入哪一个! //这时候就会直接抛异常: // NoUniqueBeanDefinitionException 不唯一 Bean 异常。

解决办法:搭配 @Qualifier 指定 Bean 名称

@Autowired @Qualifier("userServiceImpl") // 指定bean名字 private UserService userService;

@Qualifier是按 Bean 名称筛选,和 byType 配合使用。

先用 byType 找到所有同类型 Bean,再根据名字从中挑选一个。


四、byName(按名称注入)

byName:根据「Bean 的名字 (beanName)」进行匹配注入。

@Resource优先规则:拿【变量名】当作 beanName,去容器查找 bean。

@Resource private UserService abc;

👉 变量名是abc→@Resource第一步:去容器找 beanName = "abc"的 Bean。


1、Bean 默认名字规则(@Service/@Component)

当你写:

@Service public class UserServiceImpl implements UserService{ }

Spring 默认生成 beanName:类名首字母小写→userServiceImpl✅

这个 Bean 在容器里名字:userServiceImpl,类型:UserServiceImpl(实现了 UserService)

此时容器里:beanName=userServiceImpl,类型 =UserServiceImpl

示例

@Resource private UserService abc;
  1. 第一步:@Resource拿变量名abc,去容器搜索beanName="abc"
  2. 容器里没有叫 abc 的 Bean!(只有userServiceImpl)
  3. byName 查找失败 →降级 byType
  4. 按类型UserService去容器找 Bean,找到userServiceImpl注入成功。

👉 所以这个代码不会报错,可以正常运行,只是 byName 没命中,走了 byType 兜底。


2、那什么时候 byName 能命中?两种方式

方式 1:让 Bean 的名字和变量名一致

@Service("abc") // 手动指定beanName为abc public class UserServiceImpl implements UserService{ }
@Resource private UserService abc; //变量名abc
  1. @Resource拿变量名abc,去容器找 beanName=abc
  2. ✅ 找到了!直接注入,不走 byType。

方式 2:变量名等于默认 beanName

@Service public class UserServiceImpl implements UserService{ } // beanName默认:userServiceImpl
@Resource private UserService userServiceImpl; //变量名=userServiceImpl

变量名和 beanName 一致,byName 直接命中。


三、手动指定 name 属性,跳过变量名

@Resource(name="xxx")会忽略变量名,直接用你写的名字去查找:

// 直接指定去找beanName="userServiceImpl",不管变量名叫什么 @Resource(name = "userServiceImpl") private UserService abc;

哪怕变量名叫 abc,这里也不会拿 abc 去匹配,优先用 name 属性的值。


五、byName和byType放一起对比

// 场景:容器中只有一个Bean:beanName=userServiceImpl,类型UserService // @Autowired:只看类型UserService,变量名随便写abc,完全不影响 @Autowired private UserService abc; // @Resource:先拿变量名abc找beanName=abc,找不到,再按类型UserService查找 @Resource private UserService abc;

六、表格对比

特性@Autowired@Resource
来源Spring 框架注解JSR-250 Java 标准注解
默认注入方式byType(按类型)byName(按名称)→找不到再 byType
多 Bean 处理需要配合 @Qualifier 指定名字优先变量名,也可 name 属性指定
required 属性✅ 支持 @Autowired (required=false)❌ 无
构造方法注入✅ 支持❌ 不支持
框架耦合强耦合 Spring标准注解,切换容器(如 JBoss)不用改代码

七、一句话总结

  1. @Autowired:Spring 提供,默认按类型注入,多实例搭配@Qualifier,支持构造注入。
  2. @Resource:Java 标准,先按名字,名字找不到再按类型,不能用于构造器注入。

八、开发使用建议

  • SpringBoot 项目,绝大多数场景推荐@Autowired(构造注入最佳实践)
  • 如果想降低框架耦合,或者想直接按变量名匹配 bean,可以用@Resource。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询