为了账号安全,请及时绑定邮箱和手机立即绑定

为什么Spring的ApplicationContext.getBean被认为是糟糕的呢?

为什么Spring的ApplicationContext.getBean被认为是糟糕的呢?

临摹微笑 2019-08-03 07:03:57
为什么Spring的ApplicationContext.getBean被认为是糟糕的呢?我问了一个一般的Spring问题:自动浇铸春豆有多个人回应说是春天的ApplicationContext.getBean()应该尽量避免。那是为什么?否则,我应该如何访问我配置的Spring创建的bean?我在一个非web应用程序中使用Spring,并计划访问一个共享ApplicationContext对象如LiorH所述.修正我接受下面的答案,但这是马丁·福勒的另一个选择。讨论依赖注入与使用服务定位器的优点(这与调用包装的ApplicationContext.getBean()).在某种程度上,福勒说,“对于服务定位器,应用程序类通过消息显式地向定位器请求[服务]。对于注入,没有显式请求,服务出现在应用程序类中,因此出现了控制反转。控制反转是框架的一个共同特征,但它是要付出代价的。当您尝试调试时,它往往很难理解并导致问题。所以总的来说,我宁愿避免它[控制反转],除非我需要它。这并不是说这是一件坏事,只是我认为它需要为自己辩护,而不是更直截了当的选择。"
查看完整描述

3 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

我在对另一个问题的评论中提到了这一点,但是控制反转的整个想法是您的类中没有一个知道或关心它们是如何得到它们所依赖的对象的。..这使得随时更改给定依赖项的实现类型变得非常容易。它还使类易于测试,因为您可以提供依赖项的模拟实现。最后,它使类更简单更多地关注他们的核心责任。

呼叫ApplicationContext.getBean()不是倒置控制!尽管更改为给定bean名配置的实现仍然很容易,但该类现在直接依赖Spring来提供该依赖项,并且无法以任何其他方式获得它。您不能只在测试类中创建自己的模拟实现并亲自将其传递给它。这基本上违背了Spring作为依赖注入容器的目的。

你想说的任何地方:

MyClass myClass = applicationContext.getBean("myClass");

例如,您应该声明一个方法:

public void setMyClass(MyClass myClass) {
   this.myClass = myClass;}

然后在您的配置中:

<bean id="myClass" class="MyClass">...</bean><bean id="myOtherClass" class="MyOtherClass">
   <property name="myClass" ref="myClass"/></bean>

然后Spring会自动注入myClassmyOtherClass.

以这种方式声明每件事,在根本上都有如下内容:

<bean id="myApplication" class="MyApplication">
   <property name="myCentralClass" ref="myCentralClass"/>
   <property name="myOtherCentralClass" ref="myOtherCentralClass"/></bean>

MyApplication是最核心的类,并且至少间接地依赖于程序中的所有其他服务。当引导时,在main方法,您可以调用applicationContext.getBean("myApplication")但你不需要打电话getBean()其他地方!




查看完整回答
反对 回复 2019-08-05
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

选择服务定位器而不是反转控制(IoC)的原因是:

  1. 对其他人来说,服务定位器在代码中更容易遵循。IoC是“神奇的”,但是维护程序员必须了解您复杂的Spring配置和所有的位置,才能弄清楚您是如何连接对象的。

  2. 对于调试配置问题,IoC是很糟糕的。在某些类型的应用程序中,当配置错误时,应用程序不会启动,并且您可能没有机会逐步了解调试器正在发生的事情。

  3. IoC主要是基于XML的(注释改进了一些东西,但是仍然有很多XML)。这意味着开发人员不能在您的程序上工作,除非他们知道Spring定义的所有神奇标记。它不够好,不能再了解Java了。这阻碍了经验较少的程序员。当更简单的解决方案(如ServiceLocator)满足相同的需求时,使用更复杂的解决方案实际上是很糟糕的设计)。另外,对诊断XML问题的支持比对Java问题的支持要弱得多。

  4. 依赖注入更适合于较大的程序。大多数情况下,额外的复杂性是不值得的。

  5. 经常使用Spring,以防“以后可能要更改实现”。没有SpringIoC那样的复杂性,还有其他方法可以实现这一点。

  6. 对于Web应用程序(JavaEEWAR),Spring上下文在编译时被有效地绑定(除非您希望操作符在爆炸性的WAR中对上下文进行搜索)。您可以让Spring使用属性文件,但是对于Servlets,属性文件需要位于预先确定的位置,这意味着您不能在同一个盒子上部署多个相同时间的servlet。您可以在servlet启动时使用Spring和JNDI来更改属性,但是如果您使用JNDI作为管理员可修改的参数,那么Spring本身的需求就会减少(因为JNDI实际上是一个服务定位器)。

  7. 使用Spring,如果Spring向您的方法调度,您可能会失去程序控制。这很方便,适用于许多类型的应用程序,但不是全部。您可能需要在初始化期间创建任务(线程等)时控制程序流,或者需要Spring不知道内容何时绑定到WAR的可修改资源。

Spring非常适合事务管理,并具有一些优势。只是IoC在许多情况下可能过于工程化,给维护人员带来了不必要的复杂性。不考虑不首先使用国际奥委会的方法,就不要自动使用国际奥委会。


 


查看完整回答
反对 回复 2019-08-05
  • 3 回答
  • 0 关注
  • 3821 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信