【问题标题】:What is the difference between @Inject and @Autowired in Spring Framework? Which one to use under what condition?Spring Framework 中的@Inject 和@Autowired 有什么区别?在什么条件下使用哪一种?
【发布时间】:2011-10-31 20:09:40
【问题描述】:

我正在浏览一些关于 SpringSource 的博客,在其中一个博客中,作者使用的是 @Inject,我想他也可以使用 @Autowired

这是一段代码:

@Inject private CustomerOrderService customerOrderService;

我不确定@Inject@Autowired 之间的区别,如果有人解释它们的区别以及在什么情况下使用哪一个,我将不胜感激?

【问题讨论】:

标签: java spring dependency-injection autowired inject


【解决方案1】:

假设您在这里指的是javax.inject.Inject 注释。 @Inject 是 Java EE 6 (JSR-299) read more 中引入的 Java CDI (Contexts and Dependency Injection) 标准的一部分。 Spring 已选择支持将 @Inject 注释与其自己的 @Autowired 注释同义使用。

所以,回答你的问题,@Autowired 是 Spring 自己的注释。 @Inject 是称为 CDI 的 Java 技术的一部分,它定义了类似于 Spring 的依赖注入标准。在 Spring 应用程序中,这两个注解的工作方式与 Spring 决定支持一些 JSR-299 注解的方式相同。

【讨论】:

  • 所以理论上如果你使用@Inject 你可以用另一个DI框架替换spring,例如以同样的方式 Guice 和注入你的依赖项。
  • 冒着迂腐的风险:@Inject 是一个独立于 CDI (JSR-299) 的 JSR (JSR-330)。
  • 如果你只依赖 JSR-* 注释,当然,你可以替换你的 DI 框架。但是你会吗?一旦你开始使用 spring,很可能你已经使用了更多的它,而不仅仅是 DI。你不会只是做出改变;即使你这样做了,也不是一些搜索和替换将决定这一举措的成败。另一方面,Spring 自己的注解为您提供了更多功能。掌握一个好的框架会给你带来更多的好处。
  • 我同意你的观点,我们不会经常更改 DI 框架。但是,如果我们的源代码有多个包,并且如果您想构建一个想要在多个项目之间共享的通用包,然后使用 @Inject JSR 注释比使用 @Autowired 更好,后者使用 spring DI 锁定您的代码库。
  • 单独使用@Inject 并不能确保框架的独立性。您还需要声明不依赖于框架的机制(如 Spring 的 @Componentapplication.xml)的可注入 bean,但在类级别上使用 @Named@Singleton。不知道今天是否有任何 Spring 项目真的声明了这样的 bean - 我什至从未听说过任何从 Spring 迁移到 JEE 的项目......
【解决方案2】:

这是一个blog post,它比较了@Resource@Inject@Autowired,看起来做得相当全面。

来自链接:

除了测试 2 和 7 之外,配置和结果是 完全相同的。当我在引擎盖下查看时,我确定 “@Autowired”和“@Inject”注解的行为相同。两者的 这些注释使用“AutowiredAnnotationBeanPostProcessor”来 注入依赖。可以使用“@Autowired”和“@Inject” 可互换以注入 Spring bean。但是“@Resource” 注解使用‘CommonAnnotationBeanPostProcessor’注入 依赖关系。即使他们使用不同的后处理器类 它们的行为几乎相同。下面是他们的总结 执行路径。

作者引用的测试 2 和 7 分别是“按字段名称注入”和“尝试使用错误的限定符解析 bean”。

结论应该为您提供所需的所有信息。

【讨论】:

  • 那篇文章很好地解释了这三个注解。第一次刷卡后我不得不重新阅读它;但是,一篇很棒的文章。
  • 非常感谢!这篇文章回答了我在寻找 Spring 和 JavaEE 之间的差异和相似之处时的多个答案,以及我遇到的一些其他问题。
  • 请查看此链接:concretepage.com/spring/… @Inject 自动支持此功能,无需任何 (required=false) 属性
【解决方案3】:

为了处理没有连线的情况,可以使用将@Autowired required 属性设置为false 的bean。

但是当使用@Inject 时,Provider 接口与 bean 一起工作,这意味着 bean 不是直接注入,而是与 Provider 一起注入。

【讨论】:

【解决方案4】:

@Autowired@Inject 之间的主要区别(在阅读 Spring Docs 时注意到)是,@Autowired 具有“必需”属性,而 @Inject 没有“必需”属性。

【讨论】:

  • 要求是什么意思?
  • @mattymanme 来自文档,“默认情况下,只要有零个候选 bean 可用,自动装配就会失败;默认行为是将带注释的方法、构造函数和字段视为指示所需的依赖项。这个可以通过将 required 属性设置为 false 来更改行为。 例如:@Autowired(required=false)。简单来说,required 属性表示自动装配不需要该属性,该属性是如果不能自动装配,则忽略。"
  • 查看源代码 public interface Autowired { /** * 声明是否需要注解依赖。 */ boolean required() 默认为 true; } 公共接口注入 {}
【解决方案5】:

从 Spring 3.0 开始,Spring 支持 JSR-330 依赖注入注解(@Inject@Named@Singleton)。

有一个关于它们的separate section in the Spring documentation,包括与它们的 Spring 等效项的比较。

【讨论】:

  • 这里的问题,你说Spring支持JSR是什么意思?容器不支持独立于 Spring 的 JSR,并且要求容器兼容 J2EE?你的意思是它包装了功能?如果 Spring 不“支持”它,javax 中的注解是否默认仍然有效?
  • 在 JEE 容器中运行 Spring 不是必须的,您也可以在 Tomcat 等 servlet/JSP 容器中使用它,并且仍然支持 JSR-330。 Spring 是一个单独的 DI 容器,它不会与主机 JEE 服务器“交换”CDI bean,如果它是你的意思的话。您可以在 JEE 容器中使用 CDI,也可以在 Spring bean 中使用 - 但不能同时使用两者(开箱即用)。
【解决方案6】:

最好始终使用@Inject。因为它是 java 配置方法(由 sun 提供)使我们的应用程序与框架无关。因此,如果您也使用 spring,您的课程也将起作用。

如果你使用@Autowired,它只适用于spring,因为@Autowired 是spring 提供的注解。

【讨论】:

  • 太阳死了。太阳万岁。
  • 您打算多久更改一次框架?只是好奇
  • 在大多数项目中,我看到的是 Autowired 而不是 Inject。我理解答案的基本原理,但我不能投票。
【解决方案7】:

@Autowired注解在Spring框架中定义。

@Inject注解是标准注解,在标准"Dependency Injection for Java" (JSR-330)中定义。 Spring(从 3.0 版开始)支持标准 JSR-330 中定义的通用依赖注入模型。 (Google Guice frameworksPicocontainer framework 也支持这种模式)。

使用@Inject 可以注入对Provider 接口实现的引用,这允许注入延迟引用。

注解@Inject@Autowired- 几乎是完全的类比。除了@Autowired注解,@Inject注解还可用于自动绑定属性、方法和构造函数。

相对于@Autowired注解,@Inject注解没有required属性。因此,如果找不到依赖项 - 将抛出异常。

绑定属性的说明也有区别。如果注入组件的选择不明确,则应添加@Named 限定符。在类似的情况下,@Autowired 注释将添加 @Qualifier 限定符(JSR-330 定义了它自己的 @Qualifier 注释并通过此限定符定义了 @Named 注释)。

【讨论】:

【解决方案8】:

除上述之外:

  1. @Autowired bean 的默认范围是 Singleton,而使用 JSR 330 @Inject 注释它就像 Spring 的原型
  2. 在 JSR 330 中没有使用 @Inject 的 @Lazy 等效项。
  3. 在 JSR 330 中没有使用 @Inject 的 @Value 等效项。

【讨论】:

    【解决方案9】:

    @Inject 没有“必需”属性

    【讨论】:

    • 什么不是“必需的”?
    • 通过编写 @Autowired(required = false) 即使 Spring 无法连接(注入)成员,您也可以完成组件的初始化。 @Inject 在这种情况下会抛出异常,没有机会继续构造/注入。
    【解决方案10】:

    @Inject 注释是 JSR-330 注释集合之一。这具有按类型匹配、按限定符匹配、按名称匹配执行路径。 这些执行路径对 setter 和字段注入都有效。@Autowired 注释的行为与@Inject 注释相同。唯一的区别是 @Autowired 注释是 Spring 框架的一部分。 @Autowired注解也有上面的执行路径。所以我推荐@Autowired作为你的答案。

    【讨论】:

      【解决方案11】:

      @Autowired(必填=假) 默认情况下,必须满足 @Autowired 的依赖注入,因为 required 属性的值默认为 true。我们可以通过使用@Autowired(required=false) 来改变这种行为。这种情况下如果没有找到依赖注入的bean,就不会报错。

      请看 https://www.concretepage.com/spring/spring-autowired-annotation#required-false

      但是@Inject 不需要(required=false)如果没有找到依赖就不会出错

      【讨论】:

        猜你喜欢
        • 2011-11-25
        • 1970-01-01
        • 2011-08-18
        • 2019-05-06
        • 2021-10-17
        • 1970-01-01
        • 2020-01-09
        • 1970-01-01
        相关资源
        最近更新 更多