我问了一个常见的Spring问题:自动转换Spring bean,很多人回答说应该尽可能避免调用Spring的ApplicationContext.getBean()。为什么呢?

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

我在一个非web应用程序中使用Spring,并计划访问LiorH所描述的共享ApplicationContext对象。

修正案

我接受下面的答案,但这里有Martin Fowler的另一种观点,他讨论了依赖注入与使用服务定位器(本质上与调用包装的ApplicationContext.getBean()相同)的优点。

In part, Fowler states, "With service locator the application class asks for it [the service] explicitly by a message to the locator. With injection there is no explicit request, the service appears in the application class - hence the inversion of control. Inversion of control is a common feature of frameworks, but it's something that comes at a price. It tends to be hard to understand and leads to problems when you are trying to debug. So on the whole I prefer to avoid it [Inversion of Control] unless I need it. This isn't to say it's a bad thing, just that I think it needs to justify itself over the more straightforward alternative."


当前回答

其动机是编写不显式依赖Spring的代码。这样,如果您选择切换容器,就不必重写任何代码。

把容器想象成代码看不见的东西,神奇地提供它的需要,而不需要被要求。

依赖注入是“服务定位器”模式的对应。如果您打算按名称查找依赖项,那么您也可以摆脱DI容器,使用JNDI之类的东西。

其他回答

Spring的前提之一是避免耦合。定义和使用接口,DI, AOP,避免使用ApplicationContext.getBean():-)

使用Spring之类的东西的一个最酷的好处是,您不必将对象连接在一起。Zeus的头部打开,您的类就出现了,并且根据需要创建并连接了它们的所有依赖项。这是神奇的和奇妙的。

你越是说ClassINeed ClassINeed = (ClassINeed)ApplicationContext.getBean(" ClassINeed ");,你得到的魔法就越少。代码越少越好。如果您的类确实需要ClassINeed bean,为什么不直接将它连接进来呢?

也就是说,显然需要创建第一个对象。主方法通过getBean()获取一两个bean并没有什么问题,但是应该避免使用它,因为无论何时使用它,都没有真正使用Spring的所有魔力。

其思想是依赖于依赖注入(控制反转,IoC)。也就是说,您的组件已经配置了所需的组件。这些依赖关系是注入的(通过构造函数或设置函数)——你不能自己得到。

getbean()要求您在组件中显式地命名bean。相反,通过使用IoC,您的配置可以确定将使用什么组件。

这让你可以轻松地用不同的组件实现重新连接应用程序,或者通过提供模拟变量(例如,模拟DAO,这样你就不会在测试期间碰到数据库)以一种直接的方式配置测试对象。

其动机是编写不显式依赖Spring的代码。这样,如果您选择切换容器,就不必重写任何代码。

把容器想象成代码看不见的东西,神奇地提供它的需要,而不需要被要求。

依赖注入是“服务定位器”模式的对应。如果您打算按名称查找依赖项,那么您也可以摆脱DI容器,使用JNDI之类的东西。

但是,仍然有一些情况需要使用服务定位器模式。 例如,我有一个控制器bean,这个控制器可能有一些默认的服务bean,这些服务bean可以通过配置注入依赖项。 虽然这个控制器现在或以后还可以调用许多附加的或新的服务,但这些服务需要服务定位器来检索服务bean。