@资源vs @Autowired

在使用DI时,我应该使用哪个注解, @Resource ( jsr250 )或@Autowired (Spring特定)?

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

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

在3.0之前的spring,哪一个并不重要。

在Spring 3.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; 

这使得较less使用string名称,这可能是拼写错误,更难以维护。


至于原始问题:两者都没有指定注释的任何属性,按types执行注入。 区别在于:

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

@Autowired (或@Inject )和@Resource都同样适用。 但是在意义上有一个概念上的区别或者区别

  • @Resource 资源意味着给我一个名字已知资源 。 名称是从注释的setter或field的名称中提取的,或者是从名称Parameter中获取的。
  • @Inject@Autowired尝试按types连接适当的其他组件

所以,基本上这是两个截然不同的概念。 不幸的是, @Resource的Spring实现有一个内置的后备,当解决scheme名称失败时,这个后备将会启动。 在这种情况下,它将回落到@Autowired -kind分辨率types。 尽pipe这种后备方法很方便,但恕我直言,它引起了很多混淆,因为人们不了解概念上的差异,倾向于使用@Resource进行基于types的自动assembly。

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

因此,从某种意义上说,你是正确的。 我发现人们使用@Autowired@Qualifier因为它更强大。 如果不是神话,那么从一些框架转移到其他框架被认为是不太可能的,特别是在Spring的情况下。

我想强调@Jules对这个问题的回答的一个评论。 该注释带来了一个有用的链接: @Resource,@Autowired和@Inject的Spring注入 。 我鼓励你完全阅读,但是这里有一个简单的总结它的用处:

注释如何select正确的实现?

@Autowired@Inject

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

@Resource

  1. 按名称匹配
  2. 按types匹配
  3. 限定符限制(如果按名称匹配则忽略)

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

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

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

为什么我不应该使用@Qualifier

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

豆注射会减慢我的程序吗?

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


参考: 使用@Resource,@Autowired和@Inject进行Spring注入

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

小费

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

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

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

@Autowired + @Qualifier将只与弹簧DI一起工作,如果您以后要使用其他一些DI,则@Resource是不错的select。

我发现其他差异非常显着的是@Qualifier不支持dynamicbean布线,因为@Qualifier不支持占位符,而@Resource很好。

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

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

用@Autowired&@Qualifier你需要设置特定的子实现

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

它不提供占位符而@Resource你可以把占位符和使用属性文件注入特定的子实现像

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

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

 #service.name=actualService service.name=stubbedService 

希望能帮助别人:)

他们两人同样好。 使用Resource的好处是在将来如果你想要另外一个DI框架而不是Spring,你的代码改变将会简单得多。 使用Autowired,您的代码与弹簧DI紧密结合。

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

据我所知,这不是一个规范,甚至一个惯例。 标准代码使用这些注释更符合逻辑。

在这里注意: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContextSpringBeanAutowiringSupport.processInjectionBasedOnServletContext用于@Resource注解。 所以,有区别。

使用@Resource您可以执行bean自注入,可能需要运行bean事务处理器添加的所有额外逻辑,比如事务或安全相关的东西。

有了Spring 4.3+ @Autowired也可以做到这一点。