当前位置: 首页 > 面试题库 >

为什么Spring的ApplicationContext.getBean被认为是不好的?

翁和颂
2023-03-14
问题内容

我问了一个一般性的Spring问题:自动播发Spring Bean,并让多个人回答说ApplicationContext.getBean()应尽可能避免调用Spring 。这是为什么?

我还应该如何访问配置了Spring创建的Bean?

我在非Web应用程序中使用Spring,并计划按照LiorH的描述访问共享ApplicationContext对象。

修正案

我接受下面的答案,但这是Martin Fowler的另一种选择,他讨论了依赖注入与使用Service Locator(本质上与调用wrapped相同ApplicationContext.getBean())的优点。

Fowler在某种程度上说:“ 使用服务定位器,应用程序类通过向定位器的消息显式地请求[服务]。使用注入时,没有显式请求,该服务将出现在应用程序类中-因此控制反转。控制反转是框架的常见功能,但要付出一定的代价,它往往难以理解,并且在尝试调试时会导致问题。因此,总的来说,我宁愿避免这种情况。除非我需要它。这并不是说这是一件坏事,只是我觉得需要通过更直接的替代自圆其说。 “


问题答案:

我在另一个问题的评论中提到了这一点,但是Inversion of Control的整个思想是让你的类都不知道或不在乎它们如何获取所依赖的对象。这样可以轻松更改你随时使用的给定依赖项的实现类型。它还使类易于测试,因为你可以提供依赖项的模拟实现。最后,它使课程更简单,更专注于其核心职责。

调用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()在其他任何地方调用!



 类似资料:
  • 我有一个问题,关于什么是正确的做法,使用SwingU实用程序的调用稍后方法。 所以首先,我想确认我理解正确。 据我所知,对GUI的更改必须在EDT上完成,因为Swing组件不是线程安全的。invokeLater方法将Runnable作为参数,该Runnable中包含的任何内容都将在EDT上运行。因此,对Swing组件的任何调用都被放入一种队列中,在EDT上一次执行一个。 有了这些,我的问题是:使用

  • 我听到一些人说,即使在使用获得种子之后,使用也是很糟糕的。为什么会这样?我想知道事情是怎么发生的...抱歉,我又问了一个问题..但是,有什么办法可以替代这一点呢?

  • 问题内容: 为什么每个人都告诉我编写这样的代码是一种不好的做法? 我省略花括号的最大论据是,有时花括号可能是花括号的两倍。例如,以下代码为C#中的标签绘制发光效果。 您还可以获得链接usings在一起的额外好处,而不必缩进一百万次。 花括号的最常见参数涉及维护编程,以及在原始if语句及其预期结果之间插入代码会引起的问题: 问题: 想要使用该语言提供的更紧凑的语法是错误的吗?设计这些语言的人很聪明,

  • 我正在按照这篇文章撤销用户访问权限: http://bitoftech . net/2014/07/16/enable-oauth-refresh-tokens-angular js-app-using-ASP-net-we b-API-2-owin/ 现在考虑一下,在验证用户之后,我已经发布了一个访问令牌,使用期限为30分钟,如上面的文章所示,刷新令牌为1天,但是如果管理员在10分钟内删除该用户

  • 问题内容: 我有一个类的以下代码,它工作正常: 但是,我认为在该方法中实现OnClickListener是一种不好的做法。为什么会有这种不好的做法,还有什么更好的选择? 问题答案: 最好在ViewHolder中处理单击逻辑的原因是,它允许更明确的单击侦听器。如Commonsware书中所述: 很久以来,ListView行中的可单击小部件(如RatingBar)一直与行本身的单击事件发生冲突。获取可

  • 问题内容: 编辑:在上面的链接中回答的问题。 不,PHP中的“全局”与其他语言中的“全局”不同,尽管它不引入任何安全性问题,但会使其他人较难理解该代码。 OP: 项目摘要-我正在编写一个Web CMS,以使自己熟悉PHP / MySQL。为了分解代码,我对以下基本层/模块有一个概念: 数据 -MySQL表 -PHP变量 功能 -SQL- 获取/设置/等 -前端-显示页面 -后端-管理器 演示文稿