使用 @configurable 的优势与 applicationcontext.getbean 上由
答案 0 :(得分:6)
执行applicationContext.getBean()
完全违背了依赖注入的目的,因为您不再注入依赖项。应用程序上下文XML文件很好。基于注释的配置(自动布线)也很好。这样你也可以这样做:
Service service = new Service();
或更糟:
Service service = ServiceLocator.locate("service");
这两个都使您的代码难以测试。
答案 1 :(得分:1)
我将为此获得 -20 。甚至臭名昭着的马丁福勒发明了这个可怕的“依赖注射”这个名字并不认为它更适合测试:
http://martinfowler.com/articles/injection.html
人们倾向于选择依赖注入的一个常见原因是它使测试更容易。这里的要点是,要进行测试,您需要使用存根或模拟轻松替换实际服务实现。然而,依赖注入和服务定位器之间确实没有区别:两者都非常适合存根。我怀疑这个观察来自项目,人们没有努力确保他们的服务定位器可以很容易地被替换。这是持续测试有用的地方,如果你不能轻易地存储测试服务,那么这就意味着你的设计存在严重问题。
以下是我的反对意见:
DI将实现依赖性转换为接口依赖性。你的班级受到了不应该在那里的安置者的污染。是的,真正的结账过程取决于信用卡服务,邮件服务,数据库服务以及明天知道什么,但我们不应该宣传这些依赖项。它们是临时的,按需的,而不是界面价值的。也许下个月整个结账过程简化为REST调用。
性能。在一种方法之外通常不需要服务。 DI至少需要每个服务的字段变量,只要主机对象处于活动状态,就会引用它。如果服务具有每个客户端状态,则这非常糟糕。我不是一个表现敏感的人,但这感觉错了。
为生产环境编码变得更加困难。想想每次需要服务时,您使用DI添加了多少锅炉板代码。所有这些都是为了让测试更容易。首先 - 什么?!生产是第一要务;测试应该适用于它和它,而不是相反。 测试不是宗教,人们!专注于生产环境,后期担心测试。第二 - 现在测试真的很容易吗?
在测试中,您只需要模拟一些繁重且涉及VM外活动的服务。使用服务定位器,您有一个包含这些模拟服务的测试配置,您就完成了。您的结帐流程可以毫无困难地进行测试,以及所有依赖这些服务的类。在DI中,您必须在每个单元测试中手动管理这些依赖项。 -但!但是使用DI,您可以灵活地为不同的测试单元提供不同的模拟邮件服务!哦,对你有好处!
“DI鼓励统一的服务配置方式” - 仅当使用相同的框架时。实际上它与DI无关;一个框架强制实施一种配置方式,你也可以认为Spring鼓励一种统一的服务定位方式。当一个框架被广泛使用时,它可以成为事实上的标准,因此让不同的开发人员更容易相互交谈 - 只是因为网络效应,而不是因为其设计选择本身就不错。
总之,它不利于设计,不利于性能,不利于生产,不利于测试,与设置标准无关。到底有什么好处呢?这就像很久以前建立的许多愚蠢的规则和惯例的可疑起源,但我们仍然每天盲目地追随它们。这就是社会走动的原因。
编辑:转发关于DI和测试的新问题的链接Does using annotations to inject dependencies remove the main benefit of dependency injection(external configuration)?