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
@Resource vs @Autowired
提问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 @Resource
tag 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.Qualifier
meta-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:
至于原问题:两者都没有指定注解的任何属性,按类型进行注入。区别在于:
@Resource
allows you to specify a name of the injected bean@Autowired
allows 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, @Autowired
is a spring annotation. Whereas @Resource
is 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 @Autowired
with @Qualifier
because it is more powerful. Moving from some framework to some other is considered very unlikely, if not myth, especially in the case of Spring.
因此,从某种意义上说,您的建议是正确的。我发现人们使用@Autowired
with@Qualifier
因为它更强大。从某个框架转移到其他框架被认为是不太可能的,如果不是神话的话,尤其是在 Spring 的情况下。
回答by Ichthyo
Both @Autowired
(or @Inject
) and @Resource
work equally well. But there is a conceptual difference or a difference in the meaning
两者@Autowired
(或@Inject
) 和@Resource
工作得同样好。但有概念上的差异或含义上的差异
@Resource
means 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.@Inject
or@Autowired
try 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 @Resource
has 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 @Resource
for type-based autowiring.
所以,基本上这是两个截然不同的概念。不幸的是,Spring-Implementation@Resource
有一个内置的回退,当按名称解析失败时,它就会启动。在这种情况下,它会回@Autowired
退到 -kind 按类型解析。虽然这种回退很方便,但恕我直言,它会引起很多混乱,因为人们不知道概念上的差异并且倾向于使用@Resource
基于类型的自动装配。
回答by msangel
As a note here:
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext
and SpringBeanAutowiringSupport.processInjectionBasedOnServletContext
DOES NOTwork with @Resource
annotation. 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
@Resource
is often used by high-level objects, defined via JNDI. @Autowired
or @Inject
will 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?
注释如何选择正确的实现?
@Autowired
and @Inject
@Autowired
和 @Inject
- Matches by Type
- Restricts by Qualifiers
- Matches by Name
- 按类型匹配
- 限定词的限制
- 按名称匹配
@Resource
@Resource
- Matches by Name
- Matches by Type
- Restricts by Qualifiers (ignored if match is found by name)
- 按名称匹配
- 按类型匹配
- 限定符限制(如果按名称找到匹配,则忽略)
Which annotations (or combination of) should I use for injecting my beans?
我应该使用哪些注释(或组合)来注入我的 bean?
Explicitly name your component [@Component("beanName")]
Use
@Resource
with thename
attribute [@Resource(name="beanName")]
显式命名您的组件 [@Component("beanName")]
使用
@Resource
与name
属性[@Resource(名称= “beanName”)]
Why should I not use @Qualifier
?
为什么我不应该使用@Qualifier
?
Avoid @Qualifier
annotations unless you want to create a list of similar beans. For example you may want to mark a set of rules with a specific @Qualifier
annotation. 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-scan
configurations 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
回答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 @Resource
you 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+ @Autowired
is also capable of doing this.
Spring 4.3+@Autowired
也能够做到这一点。