gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 13:08:45 25 4
gpt4 key购买 nike

我问了一个常见的 Spring 问题:Auto-cast Spring Beans并且有很多人回应说应该尽可能避免调用 Spring 的 ApplicationContext.getBean() 。这是为什么?

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

我在非 Web 应用程序中使用 Spring,并计划访问共享 ApplicationContext 对象 as described by LiorH .

修订

我接受下面的答案,但这是 Martin Fowler 的替代观点,他 discusses the merits of Dependency Injection vs. using a Service Locator (本质上与调用包装的 ApplicationContext.getBean() 相同)。

Fowler 部分指出,“ 使用服务定位器,应用程序类通过向定位器发送消息显式地请求[服务]。通过注入(inject),没有显式请求,服务出现在应用程序类中 - 因此控制反转。控制反转是框架的一个常见特征,但这是有代价的。当您尝试调试时,它往往难以理解并会导致问题。所以总的来说,我宁愿避免它[控制反转],除非我需要它。这并不是说这是一件坏事,只是我认为它需要证明自己比更直接的替代方案更合理。

最佳答案

我在另一个问题的评论中提到了这一点,但控制反转的整个想法是让您的类都不知道或关心它们如何获取它们所依赖的对象。这使得您可以随时轻松更改给定依赖项的实现类型。它还使类易于测试,因为您可以提供依赖项的模拟实现。最后,它使类更简单并且更加专注于其核心职责。

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

你想说的每一个地方:

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 将自动将 myClass 注入(inject)到 myOtherClass 中。

以这种方式声明所有内容,其根源如下:

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

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

关于java - 为什么Spring的ApplicationContext.getBean被认为是不好的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34172460/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com