2011-04-13 267 views
2

我正在学习Spring使用Spring Recipes。截至目前,我明白我们可以使用Setter Injection或Injecting通过构造函数注入依赖关系。我的问题是,在现实世界的应用程序中哪些方法更经常使用,为什么?我知道它是一个主观问题,但我不能想到比本网站更好的地方来获得完美的见解。再次感谢。春天依赖注入

+0

这是一个3.方式:你可以直接注入字段。 – Ralph 2011-04-13 06:05:19

回答

4

构造函数注入优于setter注入,因为它清楚地定义了所需的依赖关系,并强制您在创建类的实例之前提供它们。使用setter注入,调用者必须找出需要哪些依赖关系,并且可能导致调用者无法注入所有必需的依赖关系。

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

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

+0

谢谢Andy .... – t0mcat 2011-04-13 02:53:22

+0

补充说的是,如果注入的构造函数注入的对象可以是'final'。 – Andrew 2013-02-09 12:13:08

0

我更喜欢构造函数注入自己。我自2005年以来一直在使用Spring。

+0

谢谢Duffymo .. – t0mcat 2011-04-13 02:55:28

2

其他的答案已经非常干净了,事实上,即使忘了设置一个字段,Constructor注入也更省力。 - 您可以不创建没有该字段的实例。因此,这个陈述的一个建议可能是:为必填字段使用构造函数注入,为可选字段使用setter或字段注入。

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

  • 领域可以final - (我喜欢最后的领域,因为化妆更容易理解)类
  • 你不能建立圈子。 (A.b和B.a) - Spring不能实例化这种构造。 (*从一个architetural点,我认为这是构造器注入的职业,不是个骗子)

但在另一方面,如果你使用构造函数注入你必须写一个比必要更多的代码。

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; 
    } 
} 

其他答案的autors会恨我的发言。

个人相信,当你有一个类,即只作为一个Spring bean(但不是没有春天),那么你可以使用字段注入而没有安全疑虑! - 因为如果Spring可以设置注释为@Ressource@Autowired(required=true)的所有字段,Spring只会将Bean放入其生命周期。正因为如此,我更喜欢野外注射,因为它使我更快(写得少,少)。对于所有初始化的东西,我使用@PostConstruct。(当然你不能在构造函数中使用这些字段,而且你也不能将它们混合使用。) - 这使得我的应用程序与IOC容器相比更强大,而不是构造器注入,但这对我的用例不是问题。 - 可以看看EJB 3.1标准,它们根本没有构造函数注入。

0

有每种方式都有优点和缺点。我认为基于构造函数的依赖注入不太容易出错,因为你正在施加某些规则并告诉你的类它的方法需要哪些依赖。更重要的是,构造器注入强制执行初始化顺序并防止循环依赖。通过setter注入,不清楚事物需要实例化的时间以及接线完成的顺序。

另一方面,二传手注射获胜的原因有很多。如果构造器很简单,少做或者什么都不做,单元测试总是更容易。此外,并非所有类的方法都需要相同的依赖关系。如果你使用Spring容器来注入你的依赖项,那么你并不总是要担心这个,因为如果你正确地配置它,Spring容器会自动为你调用你的setter。