Spring依赖注入

发布于 2024-10-31 18:40:59 字数 149 浏览 1 评论 0原文

我正在使用 Spring Recipes 学习 Spring。到目前为止,我了解到我们可以使用 Setter 注入或通过构造函数注入来注入依赖项。我的问题是,在现实世界的应用中,哪种方法更常用,为什么?我知道这是一个主观问题,但我想不出比这个网站更好的地方来获得完美的见解。再次感谢。

I am learning Spring using Spring Recipes. As of now I understood that we can inject dependencies using Setter Injection or Injecting via constructor. My question is, in real world applications what method is used more often and why? I know its a subjective question but I cant think of a better place than this site to get perfect insights. Thanks again.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

沫雨熙 2024-11-07 18:40:59

构造函数注入比 setter 注入更可取,因为它清楚地定义了需要哪些依赖项,并强制您在创建类的实例之前提供它们。通过 setter 注入,调用者必须弄清楚需要哪些依赖项,并且可能会导致调用者无法注入所有必要的依赖项。

但是,在某些情况下,您需要使用 setter 注入,例如处理仅具有默认构造函数的对象,或者设置可能存在双向关系的依赖项。

如有疑问,请尝试使用构造函数注入,并且仅在需要时才回退到 setter。

Constructor injection is preferable over setter injection because it clearly defines what dependencies are needed, and forces you to provide them before you can create an instance of the class. With setter injection, the caller has to figure out what dependencies are needed, and can lead to situations where the caller fails to inject all the necessary dependencies.

However, there are cases where you'll need to use setter injection, such as dealing with objects that only have a default constructor, or setting dependencies where there might be a bi-directional relationship.

When in doubt, try to use constructor injection, and only fall back to setters when needed.

烂人 2024-11-07 18:40:59

由于多种原因,构造函数注入被认为比 setter 注入更好,因为构造函数注入确保满足所有强制属性,并且根本不可能实例化处于无效状态的对象。请参阅这篇文章的示例:http://www. redcode.nl/blog/2010/09/setter-vs-constructor-injection/

Constructor injection is considered better than setter injection because of many reasons since constructor injection ensures all mandatory properties have been satisfied, and it is simply not possible to instantiate an object in an invalid state. Please see this post for an example: http://www.redcode.nl/blog/2010/09/setter-vs-constructor-injection/

黑寡妇 2024-11-07 18:40:59

其他答案已经非常清楚了,就忘记设置字段而言,构造函数注入更加节省。 -- 如果没有该字段,则不能创建实例。因此,此语句的一个建议可能是:对强制字段使用构造函数注入,对可选字段使用 setter 或字段注入。

构造函数注入还有另外两个影响:

  • 字段可以是 Final 字段 - (我喜欢 Final 字段,因为这样更容易理解
  • 你不能构建类的循环。 (Ab 和 Ba) - Spring 无法实例化此构造。 (*从架构的角度来看,我认为这是构造函数注入的优点,而不是缺点)

但另一方面,如果您使用构造函数注入,则必须编写不必要的代码。

public class FieldInjection {
  @Ressource //the same like @Autowired(required=true)
  private MyService myService;
}

比:

public class MethodInjection {      
  private final MyService myService;

  public MethodInjection(final MyService myService) {
     assert(myService != null);
     this.myService = myService;
  }
}

其他答案的作者会因为这个声明而讨厌我。

个人相信,当你有一个类时,它仅用作 Spring Bean (但不是没有Spring)那么你就可以使用现场注入而无需担心安全问题! - 因为只有当 Spring 能够设置 @Ressource@Autowired(required=true) 注解的所有字段时,Spring 才会将 Bean 放入其生命周期。因此,我更喜欢字段注入,因为它使我更快(更少的写入和更少的读取)。对于所有初始化内容,我使用 @PostConstruct。 (当然,您不能使用构造函数中的字段。并且您不能真正将它们混合在一起。) - 这将我的应用程序与 IOC 容器的联系比构造函数注入更强,但这对我的用例来说不是问题。 - 你可以看看 EJB 3.1 标准,它们根本没有构造函数注入。

The other answers are already very clean on the fact, that Constructor injection is more save, in terms of forget to set a field. -- You can just not create the instance without the field. So one advice from this statements could be: use constructor injection for mandatory fields and setter or field injection for optional fields.

And Constructor Injection has two other impacts:

  • the fields can be final - (I like final fields, because the make understanding easier)
  • you can not build circles of classes. (A.b and B.a) - Spring can not instantiate this construction. (*From a architetural point of view, I think this is a pro of constructor injection, not a con)

But on the other hand, if you use constructor injection you have to write a more code than necessary.

public class FieldInjection {
  @Ressource //the same like @Autowired(required=true)
  private MyService myService;
}

is much shorter than:

public class MethodInjection {      
  private final MyService myService;

  public MethodInjection(final MyService myService) {
     assert(myService != null);
     this.myService = myService;
  }
}

The autors of the other answers will hate me for that statement.

I personally believe that when you have a Class, that is only used as a Spring Bean (but not without Spring) then you can use field Injection without that safety doubt! - Because Spring will only put the Bean in its lifecycle if it can set all fields annotated by @Ressource or @Autowired(required=true). Because of this I prefer field injection because it makes my faster (less to write and less to read). And for all initialialization stuff, I use @PostConstruct. (Of course you can not use the fields in the constructor. And you can not really mix them both.) - That ties my Application much stronger to an IOC container than constructor injetion, but this is not a problem for my usecase. - May you have a look at EJB 3.1 standard, they do not have constructor injection at all.

帅的被狗咬 2024-11-07 18:40:59

我自己更喜欢构造函数注入。我从 2005 年起就开始使用 Spring。

I prefer constructor injection myself. I've been using Spring since 2005.

泼猴你往哪里跑 2024-11-07 18:40:59

每种方式都有优点和缺点。我认为基于构造函数的依赖注入不太容易出错,因为您施加了某些规则并告诉您的类其方法需要哪些依赖项。更重要的是,构造函数注入强制执行初始化顺序并防止循环依赖。通过设置器注入,并不清楚需要按什么顺序实例化以及何时完成连接。

另一方面,setter 注入获胜也是有原因的。如果构造函数简单且执行的操作较少,或者根本不执行任何操作,那么单元测试总是会更容易。此外,并非类的所有方法都需要相同的依赖项。如果您使用 Spring 容器来注入依赖项,那么您不必总是担心这一点,因为如果您配置正确,Spring 容器会自动为您调用 setter。

There are pros and cons to each way. I would argue that constructor based dependency injection is less error prone, because you are imposing certain rules and telling your class which dependencies its methods needs. More importantly, constructor injection enforces the order of initialization and prevents circular dependencies. With setter injection it is not clear in which order things need to be instantiated and when the wiring is done.

On the other hand, there are reasons why setter injection wins. Unit testing is always easier if constructors are simple and do less, or do nothing at all. Besides, not all methods of a class require the same dependencies. If you use the Spring container to inject your dependencies, then you don’t always have to worry about this because the Spring container will automatically call your setters for you if you configure it correctly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文