@资源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
- 按types匹配
- 限定符限制
- 按名称匹配
@Resource
- 按名称匹配
- 按types匹配
- 限定符限制(如果按名称匹配则忽略)
我应该使用哪些注释(或组合)来注入我的bean?
-
显式命名你的组件[@Component(“beanName”)]
-
使用带有
name
属性的@Resource [@Resource(name =“beanName”)]
为什么我不应该使用@Qualifier
?
避免使用@Qualifier
注释,除非您想创build一个类似bean的列表。 例如,您可能需要使用特定的@Qualifier
批注标记一组规则。 这种方法使得将一组规则类插入可用于处理数据的列表变得简单。
豆注射会减慢我的程序吗?
扫描组件的特定包[context:component-scan base-package="com.sourceallies.person"]
。 虽然这将导致更多的component-scan
configuration,但它减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.processInjectionBasedOnCurrentContext
和SpringBeanAutowiringSupport.processInjectionBasedOnServletContext
用于@Resource
注解。 所以,有区别。
使用@Resource
您可以执行bean自注入,可能需要运行bean事务处理器添加的所有额外逻辑,比如事务或安全相关的东西。
有了Spring 4.3+ @Autowired
也可以做到这一点。