@Resource 与 @Autowired 的对比分析

@Resource 与 @Autowired 的对比分析

技术背景

在Java开发中,依赖注入(DI)是一种重要的设计模式,它有助于实现松耦合的代码结构。Spring框架为依赖注入提供了强大的支持,其中 @Resource@Autowired 是两个常用的注解。@Resource 是JSR - 250标准的注解,而 @Autowired 是Spring特有的注解。了解它们的区别和适用场景,对于开发者正确使用依赖注入至关重要。

实现步骤

1. 环境准备

首先,确保你的项目中已经引入了Spring框架。如果你使用Maven,可以在 pom.xml 中添加以下依赖:

1
2
3
4
5
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>版本号</version>
</dependency>

2. 创建接口和实现类

假设我们有一个 Parent 接口和两个实现类 ActualServiceStubbedService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
interface Parent {
void doSomething();
}

@Service("actualService")
class ActualService implements Parent {
@Override
public void doSomething() {
System.out.println("ActualService is doing something.");
}
}

@Service("stubbedService")
class StubbedService implements Parent {
@Override
public void doSomething() {
System.out.println("StubbedService is doing something.");
}
}

3. 使用 @Autowired 进行依赖注入

1
2
3
4
5
6
7
8
9
10
@Component
public class AutowiredExample {
@Autowired
@Qualifier("actualService")
private Parent parent;

public void performAction() {
parent.doSomething();
}
}

4. 使用 @Resource 进行依赖注入

1
2
3
4
5
6
7
8
9
@Component
public class ResourceExample {
@Resource(name = "actualService")
private Parent parent;

public void performAction() {
parent.doSomething();
}
}

核心代码

@Autowired 示例

1
2
3
@Autowired
@Qualifier("actualService")
private Parent parent;

@Resource 示例

1
2
@Resource(name = "actualService")
private Parent parent;

最佳实践

  • 使用 @Resource 的场景
    • 当需要通过名称精确匹配注入的Bean时,优先使用 @Resource。例如,在注入集合或Map类型的Bean时,@Resource 更合适,因为 @Autowired 无法正确处理类型匹配。
    • 考虑到代码的可移植性,如果未来可能会使用其他依赖注入框架,@Resource 是更好的选择。
  • 使用 @Autowired 的场景
    • 当根据类型进行注入时,@Autowired 是一个不错的选择。可以结合 @Qualifier 来进一步缩小匹配范围。
    • 对于构造函数、多参数方法的注入,@Autowired 更合适,因为 @Resource 只支持字段和单参数的setter方法。

常见问题

1. @Autowired 注入集合或Map类型的Bean失败

这是因为 @Autowired 主要基于类型进行匹配,而集合或Map类型的匹配规则不适用。可以使用 @Resource 来解决这个问题。

2. @Resource 注入时类型不匹配

如果 @Resource 注解的字段名与容器中Bean的id匹配,但类型不同,Spring会抛出 org.springframework.beans.factory.BeanNotOfRequiredTypeException。这是因为 @Resource 首先按名称匹配Bean。

3. 无法使用 @Resource 进行动态Bean注入

如果需要根据配置文件动态注入Bean,@Resource 支持使用占位符,而 @Autowired 结合 @Qualifier 不支持。例如:

1
2
@Resource(name = "${service.name}")
private Parent parent;

其中 service.name 可以在属性文件中配置。


@Resource 与 @Autowired 的对比分析
https://119291.xyz/posts/2025-04-22.resource-vs-autowired-comparison/
作者
ww
发布于
2025年4月22日
许可协议