切换语言为:繁体

一文讲明白@Resource和@Autowired区别

  • 爱糖宝
  • 2024-08-21
  • 2067
  • 0
  • 0

在Spring框架中,依赖注入(Dependency Injection,DI)是核心功能之一,通过它可以轻松管理对象的生命周期及其依赖关系。在实际开发中,@Resource@Autowired是常见的依赖注入注解,但它们的功能、使用场景以及推荐使用的方式存在一定的差异。本文将详细解释这两者的区别,并探讨为何近年来@Autowired不再被推荐使用。

1. @Resource@Autowired的基本概念

1.1 @Resource

@Resource是由JSR-250规范定义的注解,是Java EE标准的一部分。它可以用于字段、方法和类,并通过名称或类型进行依赖注入。@Resource注解通常使用在应用中需要与JNDI、EJB等Java EE服务集成的场景下。

  • 按名称注入:默认情况下,@Resource会根据字段或方法的名称进行注入。Spring会首先尝试在上下文中查找与字段名称匹配的Bean,如果找到则注入该Bean。

  • 按类型注入:如果按名称无法找到匹配的Bean,@Resource将尝试按类型查找与字段类型匹配的Bean。

@Resource
private MyService myService;

1.2 @Autowired

@Autowired是Spring框架提供的注解,专门用于依赖注入。与@Resource不同,@Autowired默认是按类型进行注入的。如果在上下文中有多个同类型的Bean,Spring会使用@Qualifier注解来进一步指定注入的Bean。

  • 按类型注入@Autowired注解会根据字段或方法参数的类型在上下文中查找匹配的Bean,并进行注入。

  • 强制依赖:默认情况下,@Autowired是必需的,即如果找不到匹配的Bean,Spring将抛出异常。可以通过设置required=false来使其成为可选依赖。

@Autowired 
private MyService myService;

2. @Resource@Autowired的详细区别

2.1 注解来源与兼容性
  • @Resource:属于Java标准的一部分(JSR-250),与Spring无关,因此在Java EE和Spring应用中都可以使用。由于它是Java原生注解,因此与其他Java EE技术栈(如EJB、JPA)有良好的兼容性。

  • @Autowired:特定于Spring框架,无法在非Spring环境中使用。它是Spring框架提供的核心功能之一,主要用于Spring应用中的依赖注入。

2.2 注入方式
  • @Resource:默认按名称注入,若找不到则按类型注入。可以通过name属性显式指定要注入的Bean名称。

  • @Autowired:默认按类型注入,若有多个同类型的Bean时,需要结合@Qualifier@Primary注解来明确指定注入的Bean。

2.3 使用场景
  • @Resource:通常用于需要与Java EE其他技术集成的场景,或在不依赖Spring框架的环境中使用。

  • @Autowired:主要用于Spring应用中,特别是当应用高度依赖Spring的DI功能时。

2.4 可配置性
  • @Resource:通过name属性可以显式指定Bean的名称,从而提供更精确的控制。

  • @Autowired:无法通过注解直接指定Bean名称,而是依赖于类型匹配。需要结合@Qualifier来指定特定的Bean。

3. 为什么不再推荐使用@Autowired

随着Spring的不断演进,@Autowired的使用逐渐被更现代的方式所替代,原因主要有以下几点:

3.1 @Autowired的隐式依赖

@Autowired默认按类型注入,容易导致代码对Spring容器的隐式依赖性增强,从而降低了代码的可测试性和灵活性。在单元测试中,如果不启动Spring上下文,@Autowired注解无法正常工作,导致测试复杂性增加。

3.2 推荐使用构造函数注入

Spring团队和许多开发者现在更推荐使用构造函数注入,而非字段注入。构造函数注入更符合依赖注入的原则,可以确保Bean的完整性,避免循环依赖问题。同时,构造函数注入的代码更容易测试,因为可以直接在构造函数中传递Mock对象。

public class MyService {
    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
}

3.3 @Autowired注解滥用

由于@Autowired的便捷性,容易导致开发者滥用它,随意地在任何类中注入依赖,结果导致代码结构混乱,职责不清。过度依赖@Autowired可能使得代码维护和重构变得更加困难。

3.4 Spring Boot和@ConfigurationProperties

在Spring Boot中,@ConfigurationProperties注解被广泛使用,它能够更加优雅地绑定外部配置到Bean中,并且推荐使用构造函数注入方式。这样不仅增强了配置的灵活性,还提升了代码的可读性和维护性。

@ConfigurationProperties(prefix = "app.config")
public class AppConfig {
    private String url;
    private int timeout;

    public AppConfig(String url, int timeout) {
        this.url = url;
        this.timeout = timeout;
    }

    // getter and setter
}

4. 结论

@Resource@Autowired在Spring框架中都是用于实现依赖注入的注解,但它们的使用场景、功能和推荐程度各有不同。@Resource适用于需要与Java EE技术集成的场景,而@Autowired主要在Spring应用中使用。随着Spring框架的发展,@Autowired逐渐不再被推荐,取而代之的是构造函数注入等更加现代和灵活的依赖注入方式。

在现代的Spring开发中,使用构造函数注入不仅能够提高代码的可测试性和灵活性,还能避免许多潜在的问题。因此,在新项目或现有项目中逐步减少@Autowired的使用,是一个值得考虑的方向。

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.