@Autowired和@Resource的区别
Autowired和Resource都是用来做依赖注入的注解但它们的来源、装配规则、支持范围和使用场景有明显区别。很多面试会直接问“两者有什么区别”回答时最好从来源、匹配方式、支持位置、属性、处理类几个维度展开。一、来源不同注解来源全限定名AutowiredSpring 框架org.springframework.beans.factory.annotation.AutowiredResourceJSR-250 标准JDK / Jakartajavax.annotation.ResourceJava 8或jakarta.annotation.ResourceSpring Boot 3Autowired是 Spring 专有的。Resource是 Java 标准库的一部分Spring 对它提供了支持。在非 Spring 环境比如标准 Java EE 容器中Resource仍然可用而Autowired不行。二、默认装配规则不同这是两者最核心的差异。Autowired 默认按类型byType装配AutowiredprivateUserDaouserDao;Spring 先在容器中查找UserDao类型的 Bean。如果只找到一个直接注入。如果找到多个再按字段名或参数名去匹配 Bean 的名称。如果名称也匹配不上会尝试Primary标记的 Bean最后才用Qualifier指定。Resource 默认按名称byName装配ResourceprivateUserDaouserDao;如果不指定name属性Resource会把字段名userDao作为 Bean 名称去查找。找到就直接注入。如果按名称找不到才回退到按类型匹配。简单记Autowired先看类型Resource先看名字。三、指定名称的方式不同Autowired 指定名称需要配合QualifierAutowiredQualifier(userDaoImpl)privateUserDaouserDao;Resource 指定名称直接用name属性Resource(nameuserDaoImpl)privateUserDaouserDao;Resource写起来更简洁。Resource还支持type属性可以指定类型Resource(typeUserDao.class)privateUserDaouserDao;四、支持注入的位置不同注入位置AutowiredResource字段✅ 支持✅ 支持Setter 方法✅ 支持✅ 支持构造器✅ 支持❌ 不支持方法参数如Bean方法✅ 支持❌ 不支持Autowired支持构造器注入这是 Spring 官方推荐的方式。Resource不支持构造器注入只能用于字段和 Setter。五、required 属性与可选依赖Autowired有required属性Autowired(requiredfalse)privateUserDaouserDao;找不到匹配的 Bean 时注入null不报错。Resource没有required属性。默认必须找到匹配的 Bean找不到就抛NoSuchBeanDefinitionException。如果需要可选依赖只能用Autowired(required false)。六、对 Primary 的支持不同Autowired支持Primary。当同类型有多个 Bean 时会优先选择标记了Primary的那个。Resource不支持Primary。它优先按名称匹配按类型回退时也不会考虑Primary同类型多个 Bean 时会直接抛NoUniqueBeanDefinitionException。七、底层处理类不同注解处理类AutowiredAutowiredAnnotationBeanPostProcessorResourceCommonAnnotationBeanPostProcessor两个处理类都实现了BeanPostProcessor在 Bean 生命周期的属性填充阶段populateBean()执行注入。AutowiredAnnotationBeanPostProcessor同时处理Autowired、Value、Inject。CommonAnnotationBeanPostProcessor同时处理Resource、PostConstruct、PreDestroy。八、使用场景对比场景推荐注解原因构造器注入AutowiredResource不支持需要可选依赖Autowired(required false)Resource不支持按名称注入Resource直接写name比Autowired Qualifier简洁同类型多 Bean其中一个为PrimaryAutowiredResource不支持Primary非 Spring 环境ResourceJSR 标准可移植Spring Boot 3 项目两者均可Resource需要jakarta.annotation-api九、代码示例对比Autowired 写法ServicepublicclassOrderService{AutowiredQualifier(aliPayService)privatePaymentServicepaymentService;Autowired(requiredfalse)privateLogServicelogService;privatefinalUserDaouserDao;AutowiredpublicOrderService(UserDaouserDao){this.userDaouserDao;}}Resource 写法ServicepublicclassOrderService{Resource(namealiPayService)privatePaymentServicepaymentService;ResourceprivateUserDaouserDao;// 按字段名匹配// 不支持构造器注入}十、常见问题1. 同类型多 Bean 时 Resource 报错NoUniqueBeanDefinitionException: expected single matching bean but found 2原因按名称没找到回退到按类型发现多个同类型 Bean。解决显式指定name属性。2. Resource 在 Spring Boot 3 中找不到包Spring Boot 3 使用jakarta.annotation.Resource需要确认jakarta.annotation-api依赖已引入。spring-boot-starter默认包含。3. Autowired 构造器注入循环依赖构造器注入无法解决循环依赖会抛BeanCurrentlyInCreationException。Resource只支持字段和 Setter 注入循环依赖可以通过三级缓存解决。4. 静态字段注入两者都不能直接注入静态字段。需要通过实例方法赋值给静态变量。十一、总结对比维度AutowiredResource来源Spring 专有JSR-250 标准默认匹配按类型按名称指定名称Qualifiername属性指定类型默认按类型type属性构造器注入✅ 支持❌ 不支持方法参数注入✅ 支持❌ 不支持required 属性✅ 支持❌ 不支持Primary 支持✅ 支持❌ 不支持处理类AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor适用场景Spring 生态、构造器注入、可选依赖按名称注入、非 Spring 环境选择哪个取决于具体场景。需要构造器注入、可选依赖或Primary时用Autowired。需要按名称注入、代码更简洁时用Resource。在 Spring Boot 项目中两者可以混用但建议团队统一风格避免维护成本。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →