【Java 面试篇】@Autowire和@Resource的区别

【Java 面试篇】@Autowire和@Resource的区别

面试系列测试代码请参考:博主的Gitee仓库

  • 说说@Autowired和@Resource的区别

    在Spring中,@Autowired和@Resource都是用于注入Bean的注解。它们的作用相似,但是它们的注入方式和使用场景略有不同。

    1. @Autowired

      @Autowired注解是Spring提供的一种自动装配的方式,它可以自动将匹配类型的Bean注入到目标Bean中。当一个Bean中有多个与要注入的类型相匹配的Bean时,@Autowired可以通过@Qualifier注解指定要注入的Bean的名称。

      @Autowired注解默认按照类型匹配Bean,如果一个Bean没有匹配类型的Bean,则会抛出NoSuchBeanDefinitionException异常。但是,可以使用@Autowired(required = false)来避免这种异常的抛出,这样如果没有匹配的Bean,则会将该属性设置为null。

    2. @Resource

      @Resource注解也是Spring提供的一种自动装配的方式,它可以根据Bean的名称或类型自动注入Bean。@Resource注解有两个重要的属性:name和type。name属性指定要注入的Bean的名称,type属性指定要注入的Bean的类型。

      @Resource注解按照名称和类型进行匹配,如果指定了name属性,则会按照名称进行匹配;如果没有指定name属性,则会按照类型进行匹配。如果没有找到匹配的Bean,则会抛出NoSuchBeanDefinitionException异常。

    需要注意的是,@Resource注解是J2EE提供的,而@Autowired注解是Spring提供的。因此,如果在非Spring环境下使用@Resource注解,可能会导致兼容性问题。

    总结:在Spring中,@Autowired注解按照类型进行匹配,@Resource注解按照名称和类型进行匹配。@Autowired注解是Spring提供的,而@Resource注解是J2EE提供的。


  • 自动装配的匹配策略有

    • default:默认匹配策略
    • byType:按照类型匹配
    • byName:按照名称匹配
  • @Autowired使用注意事项

    • 自动装配的Bean必须要被Spring管理,即:自动装配的Bean必须注入IoC容器,交给IoC容器管理。如果一个Bean没有匹配类型的Bean,则会抛出NoSuchBeanDefinitionException异常。但是,可以使用@Autowired(required = false)来避免这种异常的抛出,这样如果没有匹配的Bean,则会将该属性设置为null。

      交给Spring管理的方式有:注解配置,XML配置

    • 自动装配的Bean必须提供构造方法,默认是寻找无参构造方法,无参未找到就会找有参,如果没有找到任何一个带有参数的构造函数,则会抛出 NoSuchMethodException 异常。但是如果使用了其他的注解来声明Bean,比如使用@Component或@Service注解,这些注解中会存在默认的无参构造方法的要求。因此,在这种情况下,需要确保Bean拥有无参构造方法,否则无法正常实例化。

    • 默认采用byType策略进行匹配,当匹配到多个同类型的Bean时,编译阶段就会报错,此时需要使用@Qualifier注解指定Bean的名称(也就是改用 byName 匹配策略),Bean默认的name是类名首字母小写(可通过Component的value属性重新指定Bean的 name)

    • 为什么Spring官方不推荐在成员变量上使用@Autowired

      1. 成员变量的注入时机不确定

        将@Autowired注解标注在成员变量上时,Spring框架会在创建Bean的时候自动注入成员变量。但是,在注入成员变量之前,Spring框架还没有对该Bean进行初始化,因此,成员变量的值可能会为null,这会导致空指针异常。

      2. 无法进行final修饰的成员变量注入

        由于@Autowired注解是在运行时注入Bean的,因此它不能注入final修饰的成员变量。

      3. 不利于单元测试

        在进行单元测试时,可能需要模拟Bean的行为,此时如果将@Autowired注解标注在成员变量上,则无法通过setter方法进行Bean的mock操作,从而影响了单元测试的进行。

      因此,推荐将@Autowired注解标注在类的构造函数、setter方法或方法参数上,这样可以明确注入的时机,并且可以避免成员变量的空指针异常。同时,这种做法也更利于单元测试。

  • @Autowired和@Resource的比较

    • 功能相同。@Autowired和@Resource注解都是作为Bean对象注入的时候使用的

    • 提供方不同。@Autowired注解是Spring提供的,而@Resource注解是J2EE1本身提供的

    • 默认匹配策略不同。@Autowird注解默认通过 byType 方式注入,而@Resource注解默认通过 byName 方式注入

    • Autowired优点:

      1. 注入方式更灵活,可以通过构造函数、setter方法或者方法参数进行注入。
      2. 支持按照类型、名称或者属性名称进行注入,具有更多的匹配策略。
      3. 可以支持基于Java编程的配置,不需要依赖于注解。

      @Resource优点:

      1. 可以指定Bean的名称,从而避免了按照类型进行注入时可能存在的多个相同类型的Bean。
      2. 可以进行细粒度的控制,比如可以指定要注入的Bean的属性名,以及是否允许为null。
      3. 支持基于XML配置的方式,可以更方便地管理Bean。

      因此,如果需要灵活的注入方式,以及更多的匹配策略,建议使用@Autowired注解;如果需要更细粒度的控制,以及XML配置的支持,建议使用@Resource注解。当然,在实际开发中,两个注解也可以混合使用。


  1. J2EE:Java企业级应用程序开发规范,类似于JDBC,是一套标准,现在已经更名为JavaEE了 ↩︎

猜你喜欢

转载自blog.csdn.net/qq_66345100/article/details/129602190
今日推荐