首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >依赖注入:@Autowired和@Resource

依赖注入:@Autowired和@Resource

原创
作者头像
Eulogy
发布2025-06-29 12:15:47
发布2025-06-29 12:15:47
2440
举报
文章被收录于专栏:笔记本笔记本

@Resource和@Autowired注解的区别

Bean的默认名称是首字母小写的类型名,可以通过使用@Component、@Service、@Controller、@Bean等注解创建Bean的时候自定义该Bean的名称。

代码语言:java
复制
@Service("orderService")  // 显式指定名称为 orderService
public class UserService {
    // ...
}

@Autowired

Spring的注解,先按照类型名找,类型名有多个匹配的话再按照字段名找

查找逻辑

类型名没找到

退出

类型名找到了

继续 ------>

有@Qualifier()注解

  • 注入的时候根据@Qualifier指定的名称去找对应的Bean,并且忽略@Primary注解

无@Qualifier()注解

继续 ------>

有@Primary注解

  • Bean在创建的时候有@Primary注解,则直接返回有该注解的Bean

无@Primary注解

继续 ------>

同类型Bean只有一个

  • 找到且只有一个就直接返回该Bean

同类型Bean有多个

  • 这时根据指定名字(如果没有就按字段名)查找目标Bean的名称,找到则返回,找不到则报错

required属性

@Autowired默认required=true,找不到匹配的Bean会抛出异常。设置为false时,找不到Bean则注入null:

代码语言:java
复制
@Component
public class UserService {
    @Autowired(required = false)  // 找不到Bean时注入null,不会抛异常
    private OptionalService optionalService;
}

示例

@Primary的使用

代码语言:java
复制
@Component
public class UserService {
    @Autowired
    private UserRepository userRepository; // 会注入MySqlUserRepository
}

@Component
@Primary  // 标记为主要的实现
public class MySqlUserRepository implements UserRepository {}

@Component
public class RedisUserRepository implements UserRepository {}

@Qualifier的使用

代码语言:java
复制
@Component
public class UserService {
    @Autowired
    @Qualifier("redisUserRepository") // 明确指定要注入的Bean
    private UserRepository userRepository;
}

@Resource

这个注解是Java自带的JSR-250标准注解。Spring引入之后主动支持了这个注解,把它也作为了依赖注入的注解。它首先是根据名称查找,再按照类型查找

查找逻辑

先按照名称查找

会尝试找Bean名称为字段名的对象:

代码语言:java
复制
@Resource
private UserRepository userRepository; // 查找名为"userRepository"的Bean

也可以显式指定名字,查找Bean名称为"userRepo1"的对象:

代码语言:java
复制
@Resource(name = "userRepo1")
private UserRepository userRepository;

再按照类型查找

如果显式指定了名字但是没找到,就直接报错。如果没显式指定名字,但是按名称没找到,就会根据类型去容器中找匹配的Bean。如果找出来了多个,也会报错,只会返回找到的唯一匹配类型的Bean。

type属性

@Resource还可以通过type属性指定类型来限制查找范围:

代码语言:java
复制
@Resource(name = "userRepo1", type = UserRepository.class)
private UserRepository userRepository;

// 或者只指定类型
@Resource(type = MySqlUserRepository.class)
private UserRepository userRepository;

查找失败示例

代码语言:java
复制
@Resource  // 如果有多个UserRepository实现且没有名为userRepository的Bean
private UserRepository userRepository; // 会报错:找到多个类型匹配的Bean

性能对比

@Autowired按类型查找通常比@Resource按名称查找效率更高。这是因为:

  • Spring容器内部对按类型查找做了优化,使用类型作为key的Map结构
  • 按名称查找需要遍历更多的Bean定义信息

在大型应用中,如果没有特殊需求,推荐使用@Autowired。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • @Resource和@Autowired注解的区别
    • @Autowired
      • 查找逻辑
      • required属性
      • 示例
    • @Resource
      • 查找逻辑
      • type属性
      • 查找失败示例
    • 性能对比
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档