Java @Resource 与 @Autowired

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4093504/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:31:53  来源:igfitidea点击:

@Resource vs @Autowired

javaspringdependency-injectionannotationsautowired

提问by mlo55

Which annotation, @Resource(jsr250) or @Autowired(Spring-specific) should I use in DI?

我应该在 DI 中使用哪个注释,@Resource( jsr250) 或@Autowired(Spring-specific)?

I have successfully used both in the past, @Resource(name="blah")and @Autowired @Qualifier("blah")

我过去曾成功地使用过,@Resource(name="blah")并且@Autowired @Qualifier("blah")

My instinct is to stick with the @Resourcetag since it's been ratified by the jsr people.
Anyone has strong thoughts on this?

我的直觉是坚持使用该@Resource标签,因为它已被 jsr 人员批准。
有人对此有强烈的想法吗?

采纳答案by Bozho

In spring pre-3.0 it doesn't matter which one.

在 spring pre-3.0 中,哪一个都无关紧要。

In spring 3.0 there's support for the standard (JSR-330) annotation @javax.inject.Inject- use it, with a combination of @Qualifier. Note that spring now also supports the @javax.inject.Qualifiermeta-annotation:

在 spring 3.0 中支持标准(JSR-330)注释@javax.inject.Inject- 使用它,结合@Qualifier. 请注意,spring 现在也支持@javax.inject.Qualifier元注释:

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

So you can have

所以你可以有

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

or

或者

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

And then:

进而:

@Inject @YourQualifier private Foo foo;

This makes less use of String-names, which can be misspelled and are harder to maintain.

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



As for the original question: both, without specifying any attributes of the annotation, perform injection by type. The difference is:

至于原问题:两者都没有指定注解的任何属性,按类型进行注入。区别在于:

  • @Resourceallows you to specify a name of the injected bean
  • @Autowiredallows you to mark it as non-mandatory.
  • @Resource允许您指定注入 bean 的名称
  • @Autowired允许您将其标记为非强制性。

回答by Teja Kantamneni

Both of them are equally good. The advantage of using Resource is in future if you want to another DI framework other than spring, your code changes will be much simpler. Using Autowired your code is tightly coupled with springs DI.

他们两个都一样好。使用Resource的好处是,以后如果你想用spring以外的其他DI框架,你的代码改动会简单很多。使用 Autowired 您的代码与弹簧 DI 紧密耦合。

回答by Adeel Ansari

The primary difference is, @Autowiredis a spring annotation. Whereas @Resourceis specified by the JSR-250, as you pointed out yourself. So the latter is part of Java whereas the former is Spring specific.

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

Hence, you are right in suggesting that, in a sense. I found folks use @Autowiredwith @Qualifierbecause it is more powerful. Moving from some framework to some other is considered very unlikely, if not myth, especially in the case of Spring.

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

回答by Ichthyo

Both @Autowired(or @Inject) and @Resourcework equally well. But there is a conceptual difference or a difference in the meaning

两者@Autowired(或@Inject) 和@Resource工作得同样好。但有概念上的差异或含义上的差异

  • @Resourcemeans get me a known resource by name. The name is extracted from the name of the annotated setter or field, or it is taken from the name-Parameter.
  • @Injector @Autowiredtry to wire in a suitable other component by type.
  • @Resource意味着按名称为我获取已知资源。名称从带注释的 setter 或字段的名称中提取,或者从名称参数中获取。
  • @Inject@Autowired尝试按类型连接合适的其他组件

So, basically these are two quite distinct concepts. Unfortunately the Spring-Implementation of @Resourcehas a built-in fallback, which kicks in when resolution by-name fails. In this case, it falls back to the @Autowired-kind resolution by-type. While this fallback is convenient, IMHO it causes a lot of confusion, because people are unaware of the conceptual difference and tend to use @Resourcefor type-based autowiring.

所以,基本上这是两个截然不同的概念。不幸的是,Spring-Implementation@Resource有一个内置的回退,当按名称解析失败时,它就会启动。在这种情况下,它会回@Autowired退到 -kind 按类型解析。虽然这种回退很方便,但恕我直言,它会引起很多混乱,因为人们不知道概念上的差异并且倾向于使用@Resource基于类型的自动装配。

回答by msangel

As a note here: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContextand SpringBeanAutowiringSupport.processInjectionBasedOnServletContextDOES NOTwork with @Resourceannotation. So, there are difference.

请注意: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext并且SpringBeanAutowiringSupport.processInjectionBasedOnServletContext不适用于@Resource注释。所以,有区别。

回答by Kartik

This is what I got from the Spring 3.0.x Reference Manual:-

这是我从Spring 3.0.x 参考手册中得到的:-

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.

提示

如果您打算按名称表达注解驱动的注入,请不要主要使用 @Autowired,即使技术上能够通过 @Qualifier 值引用 bean 名称。相反,请使用 JSR-250 @Resource 注释,该注释在语义上定义为通过其唯一名称标识特定目标组件,声明的类型与匹配过程无关。

作为这种语义差异的特定结果,本身定义为集合或映射类型的 bean 不能通过 @Autowired 注入,因为类型匹配不适用于它们。对此类 bean 使用 @Resource,通过唯一名称引用特定集合或映射 bean。

@Autowired 适用于字段、构造函数和多参数方法,允许通过参数级别的限定符注释来缩小范围。相比之下,@Resource 仅支持带有单个参数的字段和 bean 属性 setter 方法。因此,如果您的注入目标是构造函数或多参数方法,请坚持使用限定符。

回答by Nicolas Zozol

@Resourceis often used by high-level objects, defined via JNDI. @Autowiredor @Injectwill be used by more common beans.

@Resource通常由通过 JNDI 定义的高级对象使用。@Autowired或者@Inject将被更常见的 bean 使用。

As far as I know, it's not a specification, nor even a convention. It's more the logical way standard code will use these annotations.

据我所知,它不是规范,甚至不是约定。更多的是标准代码将使用这些注释的逻辑方式。

回答by Stephan

I would like to emphasize one comment from @Juleson this answerto this question. The comment brings a useful link: Spring Injection with @Resource, @Autowired and @Inject. I encourage you to read it entirely, however here is a quick summary of its usefulness:

我想强调@Jules这个问题的回答的评论。评论带来了一个有用的链接:Spring Injection with @Resource、@Autowired 和 @Inject。我鼓励你完整地阅读它,但这里是它的用处的快速总结:

How annotations select the right implementation?

注释如何选择正确的实现?

@Autowiredand @Inject

@Autowired@Inject

  1. Matches by Type
  2. Restricts by Qualifiers
  3. Matches by Name
  1. 按类型匹配
  2. 限定词的限制
  3. 按名称匹配

@Resource

@Resource

  1. Matches by Name
  2. Matches by Type
  3. Restricts by Qualifiers (ignored if match is found by name)
  1. 按名称匹配
  2. 按类型匹配
  3. 限定符限制(如果按名称找到匹配,则忽略)

Which annotations (or combination of) should I use for injecting my beans?

我应该使用哪些注释(或组合)来注入我的 bean?

  1. Explicitly name your component [@Component("beanName")]

  2. Use @Resourcewith the nameattribute [@Resource(name="beanName")]

  1. 显式命名您的组件 [@Component("beanName")]

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

Why should I not use @Qualifier?

为什么我不应该使用@Qualifier

Avoid @Qualifierannotations unless you want to create a list of similar beans. For example you may want to mark a set of rules with a specific @Qualifierannotation. This approach makes it simple to inject a group of rule classes into a list that can be used for processing data.

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

Does bean injection slow my program?

bean 注入会减慢我的程序吗?

Scan specific packages for components [context:component-scan base-package="com.sourceallies.person"]. While this will result in more component-scanconfigurations it reduces the chance that you'll add unnecessary components to your Spring context.

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



Reference:Spring Injection with @Resource, @Autowired and @Inject

参考:Spring Injection with @Resource、@Autowired 和 @Inject

回答by Ali

@Autowired + @Qualifier will work only with spring DI, if you want to use some other DI in future @Resource is good option.

@Autowired + @Qualifier 仅适用于 spring DI,如果您想在未来使用其他 DI,@Resource 是不错的选择。

other difference which I found very significant is @Qualifier does not support dynamic bean wiring, as @Qualifier does not support placeholder, while @Resource does it very well.

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

For example: if you have an interface with multiple implementations like this

例如:如果你有一个像这样有多个实现的接口

interface parent {

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

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

}

with @Autowired & @Qualifier you need to set specific child implementation like

使用 @Autowired 和 @Qualifier,您需要设置特定的子实现,例如

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

which does not provide placeholder while with @Resource you can put placeholder and use property file to inject specific child implementation like

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

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

where service.name is set in property file as

其中 service.name 在属性文件中设置为

#service.name=actualService
 service.name=stubbedService

Hope that helps someone :)

希望对某人有所帮助:)

回答by Bohdan Levchenko

With @Resourceyou can do bean self-injection, it might be needed in order to run all extra logic added by bean post processors like transactional or security related stuff.

由于@Resource您可以进行 bean 自我注入,因此可能需要它来运行 bean 后处理器添加的所有额外逻辑,如事务或安全相关的东西。

With Spring 4.3+ @Autowiredis also capable of doing this.

Spring 4.3+@Autowired也能够做到这一点。