Spring面试题-@Autowired注解和@Resource注解的区别

发布于:2024-10-13 ⋅ 阅读:(4) ⋅ 点赞:(0)

简要回答

@Autowired

默认情况下,@Autowired 是按类型(byType)自动装配的。如果 Spring 容器中恰好有一个匹配的 bean 类型,它将自动注入这个 bean。如果有多个相同类型的 bean,则需要通过 @Qualifier 注解来指定注入哪一个 bean。此外,@Autowired 也可以按名称(byName)装配,但这通常需要与 @Qualifier 注解结合使用,或者将 required 属性设置为 false 并依赖于 Java 8 的默认方法或字段初始化器。

@Resource

@Resource 注解提供了两种装配方式:按名称(byName)和按类型(byType)。默认情况下,它是按名称装配的。如果找不到匹配的 bean,则回退到按类型查找。

深入理解

1、定义与来源

@Autowired

@Autowired是Spring框架提供的注解,主要用于自动装配Spring容器中的Beans。通过@Autowired,Spring会根据类型(Type)来自动查找适合的Bean并注入。

@Resource

@Resource注解来自Java标准规范(JSR-250),是Java EE(Enterprise Edition)的一部分。它允许Java EE容器管理Beans的依赖关系,支持按名称(Name)和类型(Type)进行注入。

2、注入方式

@Autowired

默认情况下,@Autowired按类型注入,如果有多个同类型的Bean,Spring会抛出NoSuchBeanDefinitionException异常。这种情况下,可以使用@Qualifier注解来指定要注入的Bean的名称。它也可以与其他Spring注解(如@Component, @Service, @Controller等)结合使用,灵活性较高。

@Resource

@Resource默认情况下是根据名称注入;它会优先查找与字段名称匹配的Bean。如果找不到对应名称的Bean,则会再根据类型查找。@Resource不像@Autowired那样依赖于Spring特有的功能,因此它可以在Java EE环境中获得更好的兼容性。

3、特性

@Autowired

  • 灵活性:支持按类型自动装配,配合@Qualifier可指定具体的Bean,能更好地处理复杂的依赖关系。
  • 必填@Autowired具有required属性,默认情况下为true。这意味着如果找不到适合的Bean,会抛出异常。可以将required设置为false,以允许注入为null。
  • 构造函数、Setter和字段@Autowired不仅支持字段注入,还可以用于构造函数和Setter方法。

@Resource

  • 遵循Java EE规范:相较于@Autowired@Resource更符合Java EE的标准,可以在一些Java EE容器中很好地工作。
  • 按名称优先@Resource优先按名称查找Bean,这有助于简化命名规则下的注入,减少问题的发生。
  • 不支持required属性@Resource没有提供类似required的属性,因此在找不到适合的Bean时,它不会直接抛出异常,而是可能会导致其他问题。

4、适用场景

@Autowired

  • 在Spring应用中,如果需要根据类型进行灵活的依赖管理,使用@Autowired是更加合适的选择。
  • 在需要进行复杂的依赖管理,比如需要指定不同的实现时,结合使用@Autowired@Qualifier会更方便。

@Resource

  • 在Java EE环境中,尤其是与EJB(Enterprise Java Beans)结合使用时,@Resource会更好地发挥作用。
  • 当Bean的结构和命名相对固定且不需要过多的变化时,使用@Resource既简单又有效。
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;

public class MyService {

    // 使用 @Autowired 注解
    @Autowired
    private MyRepository myRepository;

    // 使用 @Resource 注解
    @Resource
    private AnotherService anotherService;

    public void perform() {
        // 使用注入的Bean
        myRepository.doSomething();
        anotherService.execute();
    }
}