有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java@Resource vs@Autowired

我应该在DI中使用哪个注释,@Resourcejsr250)或@Autowired(特定于Spring)

我在过去成功地使用了@Resource(name="blah")@Autowired @Qualifier("blah")

我的本能是坚持使用@Resource标记,因为它已经得到了jsr人员的批准
有人对此有强烈的想法吗


共 (6) 个答案

  1. # 1 楼答案

    主要区别是,@Autowired是一个spring注释。而@Resource是由JSR-250指定的,正如您自己指出的。因此,后者是Java的一部分,而前者是特定于Spring的

    因此,从某种意义上说,你的建议是正确的。我发现人们使用@Autowired@Qualifier是因为它更强大。从某个框架转移到另一个框架被认为是非常不可能的,如果不是神话的话,尤其是在Spring的情况下

  2. # 2 楼答案

    我想强调@Jules关于this answer对这个问题的一点评论。该评论带来了一个有用的链接:Spring Injection with @Resource, @Autowired and @Inject。我鼓励您完整阅读,但以下是对其有用性的快速总结:

    注释如何选择正确的实现

    @Autowired@Inject

    1. 按类型匹配
    2. 限定符限制
    3. 按名称匹配

    @Resource

    1. 按名称匹配
    2. 按类型匹配
    3. 按限定符限制(如果按名称找到匹配项,则忽略)

    我应该使用哪种注释(或它们的组合)来注入bean

    1. 显式命名组件[@component(“beanName”)]

    2. 使用@Resourcename属性[@Resource(name=“beanName”)]

    为什么我不应该使用@Qualifier

    避免@Qualifier注释,除非您想创建类似bean的列表。例如,您可能希望使用特定的@Qualifier注释标记一组规则。这种方法使得将一组规则类注入到可用于处理数据的列表中变得简单

    bean注入会减慢我的程序吗

    扫描特定包中的组件[context:component-scan base-package="com.sourceallies.person"]。虽然这将导致更多的component-scan配置,但它减少了向Spring上下文添加不必要组件的可能性


    参考资料:Spring Injection with @Resource, @Autowired and @Inject

  3. # 3 楼答案

    这是我从Spring 3.0.x Reference Manual得到的:

    Tip

    If you intend to express annotation-driven injection by name, do not primarily use @Autowired, even if is technically capable of referring to a bean name through @Qualifier values. Instead, use the JSR-250 @Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.

    As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through @Autowired, because type matching is not properly applicable to them. Use @Resource for such beans, referring to the specific collection or map bean by unique name.

    @Autowired applies to fields, constructors, and multi-argument methods, allowing for narrowing through qualifier annotations at the parameter level. By contrast, @Resource is supported only for fields and bean property setter methods with a single argument. As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method.

  4. # 4 楼答案

    @Autowired+@限定符仅适用于spring DI,如果您希望在将来使用其他DI,@Resource是一个不错的选择

    我发现另一个非常重要的区别是@Qualifier不支持动态bean连接,因为@Qualifier不支持占位符,而@Resource做得很好

    例如: 如果您有一个与多个实现类似的接口

    interface parent {
    
    }
    @Service("actualService")
    class ActualService implements parent{
    
    }
    @Service("stubbedService")
    class SubbedService implements parent{
    
    }
    

    带@Autowired&@您需要设置特定子实现的限定符 像

    @Autowired
    @Qualifier("actualService") or 
    @Qualifier("stubbedService") 
    Parent object;
    

    它不提供占位符,而使用@Resource时,您可以放置占位符并使用属性文件注入特定的子实现,如

    @Resource(name="${service.name}")
    Parent object;  
    

    哪里有服务。名称在属性文件中设置为

    #service.name=actualService
     service.name=stubbedService
    

    希望对某人有所帮助:)

  5. # 5 楼答案

    无论是{}(或{})还是{}都同样有效。但这是一个概念上的差异或意义上的差异

    • @Resource表示按名称给我一个已知资源。名称从带注释的setter或字段的名称中提取,或从name参数中提取
    • @Inject@Autowired尝试按类型连接合适的其他组件

    所以,基本上这是两个截然不同的概念。不幸的是@Resource的Spring实现有一个内置的回退机制,当按名称解析失败时,该机制就会启动。在本例中,它返回到按类型的@Autowired类解析。虽然这种回退很方便,但它会引起很多混乱,因为人们不知道概念上的差异,倾向于使用@Resource进行基于类型的自动连接

  6. # 6 楼答案

    在3.0之前的春季,选择哪一个并不重要

    在Spring3.0中,支持标准(JSR-330)注释@javax.inject.Inject——使用它,并结合使用@Qualifier。请注意,spring现在还支持@javax.inject.Qualifier元注释:

    @Qualifier
    @Retention(RUNTIME)
    public @interface YourQualifier {}
    

    所以你可以

    <bean class="com.pkg.SomeBean">
       <qualifier type="YourQualifier"/>
    </bean>
    

    @YourQualifier
    @Component
    public class SomeBean implements Foo { .. }
    

    然后:

    @Inject @YourQualifier private Foo foo;
    

    这减少了字符串名称的使用,因为字符串名称可能拼写错误,并且更难维护


    至于原始问题:两者都不指定注释的任何属性,而是按类型执行注入。区别在于:

    • @Resource允许您指定注入bean的名称
    • @Autowired允许您将其标记为非强制性