@Autowired与@Resource:深入解析Spring中的依赖注入

155 阅读4分钟

在Java开发中,依赖注入(DI,Dependency Injection)是一个重要的设计模式,它能够有效解耦类之间的依赖关系,提高代码的可维护性和扩展性。@Autowired@Resource 是两种常用的注解,它们都用于依赖注入,但它们在使用场景、功能和配置上存在一些差异。本文将详细解析这两个注解的异同,并通过代码示例帮助你更好地理解它们的用法。

相同点:

@Autowired@Resource 都是用于实现依赖注入的注解,它们的主要目的是自动装配所需的依赖对象。通过这两个注解,开发者可以无需显式地在代码中通过构造函数或 setter 方法去创建对象,从而简化了对象的创建过程,减少了代码的冗余。

代码示例:

假设有一个 UserService 类,它依赖 UserRepository 类:

public class UserRepository {
    public String getUserInfo() {
        return "User info from repository.";
    }
}

public class UserService {
    private UserRepository userRepository;

    // 使用 @Autowired 注解进行自动注入
    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void showUserInfo() {
        System.out.println(userRepository.getUserInfo());
    }
}

在上述代码中,无论是通过 @Autowired 还是 @ResourceUserService 都能够自动获得 UserRepository 的实例,进行依赖注入。


不同点:

虽然 @Autowired@Resource 都实现了依赖注入,但它们在使用方式、支持的参数、以及注入的类型等方面有所不同。以下是它们的详细区别。

1. 来源:

  • @Resource 来自 JDK,属于 Java EE 规范的一部分,原本是为了解决类之间的依赖关系而设计的。
  • @Autowired 来自 Spring 框架,是 Spring 特有的注解,专门用于在 Spring 环境中进行依赖注入。

2. 支持的参数:

  • @Resource 支持更多的参数配置,最常见的两个参数是 nametype

    • name:指定要注入的 Bean 的名称。如果没有指定,Spring 会默认使用属性名来查找 Bean。
    • type:指定要注入的 Bean 类型(不过这种用法较少)。
    @Resource(name = "userRepository") 
    private UserRepository userRepository;
    

    如果没有指定 name 参数,@Resource 会默认按照属性名进行匹配。

  • @Autowired 主要支持一个参数:required。该参数表示依赖是否是必需的:

    • required = true:表示该依赖是必须的。如果 Spring 容器中没有找到匹配的 Bean,则会抛出异常。
    • required = false:表示该依赖是可选的。如果没有找到匹配的 Bean,Spring 会忽略错误。
    @Autowired(required = false) 
    private UserRepository userRepository;
    

3. 支持的注入类型:

  • @Autowired 支持三种常见的注入方式:

    • 属性注入(Field Injection)
    • 构造方法注入(Constructor Injection)
    • Setter 方法注入(Setter Injection)

    示例:构造方法注入

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
  • @Resource 只支持属性注入和 setter 方法注入,不支持构造方法注入。

    @Resource
    private UserRepository userRepository;
    

4. 默认注入方式:

  • @Autowired 默认是按类型进行注入的。如果 Spring 容器中有多个相同类型的 Bean,且没有指定名称,它会根据 Bean 的类型来注入。

    @Autowired
    private UserRepository userRepository;
    
  • @Resource 默认是按名称进行注入的。如果没有指定 name 属性,它会使用属性名作为 Bean 名称,查找相应的 Bean 进行注入。

    @Resource
    private UserRepository userRepository;
    

综合比较:

特性@Autowired@Resource
来源Spring 框架JDK(Java EE)
支持的注入方式属性注入、构造方法注入、Setter 注入属性注入、Setter 注入
支持的参数配置required(是否必须注入)name(指定 Bean 名称)、type(指定 Bean 类型)
默认注入方式按类型注入按名称注入

总结:

@Autowired@Resource 都是实现依赖注入的工具,但它们有不同的侧重点。@Autowired 是 Spring 框架提供的功能,支持更多的注入方式(如构造方法注入),并且默认按类型进行注入。而 @Resource 则是 Java EE 提供的注解,默认按名称进行注入,且支持更多的参数配置,通常用于对 Bean 名称进行精确控制。

在实际开发中,若你正在使用 Spring 或 Spring Boot,推荐使用 @Autowired,因为它支持更灵活的注入方式,并且与 Spring 环境更为契合。如果你使用的是 JDK 或 Java EE 规范,或者更喜欢按照 Bean 名称注入的方式,可以使用 @Resource

希望通过这篇文章,你能够更清楚地理解这两个注解的差异,并在实际项目中灵活选择适合的注解来实现依赖注入。