【发布时间】:2010-09-13 00:24:40
【问题描述】:
我了解依赖注入本身的好处。让我们以 Spring 为例。我也了解其他 Spring 特性的好处,如 AOP、不同类型的助手等。我只是想知道,XML 配置有什么好处,例如:
<bean id="Mary" class="foo.bar.Female">
<property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
<property name="girlfriend" ref="Mary"/>
</bean>
与普通的旧 Java 代码相比,例如:
Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);
更容易调试,编译时间检查,任何只知道java的人都可以理解。 那么依赖注入框架的主要目的是什么? (或一段显示其好处的代码。)
更新:
如果发生
IService myService;// ...
public void doSomething() {
myService.fetchData();
}
如果 myService 的实现不止一个,IoC 框架如何猜测我要注入哪个实现?如果给定接口只有一个实现,并且我让 IoC 容器自动决定使用它,那么在出现第二个实现后它将被破坏。如果一个接口故意只有一种可能的实现,那么你就不需要注入它。
看到 IoC 的一小部分配置显示它的好处会非常有趣。我使用 Spring 已经有一段时间了,我无法提供这样的例子。我可以展示单行代码来展示我使用的 hibernate、dwr 和其他框架的好处。
更新 2:
我意识到可以在不重新编译的情况下更改 IoC 配置。这真的是个好主意吗?我可以理解何时有人想要更改数据库凭据而不重新编译 - 他可能不是开发人员。在您的实践中,开发人员以外的其他人多久更改一次 IoC 配置?我认为对于开发人员而言,无需重新编译该特定类而不是更改配置。对于非开发人员,您可能希望让他的生活更轻松并提供一些更简单的配置文件。
更新 3:
接口及其具体实现之间映射的外部配置
使它具有外部性有什么好处?您不必将所有代码都放在外部,虽然您绝对可以 - 只需将其放在 ClassName.java.txt 文件中,即时手动读取和编译 - 哇,您避免了重新编译。为什么要避免编译?!
您节省了编码时间,因为您以声明方式而不是在程序代码中提供映射
我了解有时声明式方法可以节省时间。例如,我只声明一次 bean 属性和 DB 列之间的映射,hibernate 在加载、保存、构建基于 HSQL 的 SQL 等时使用此映射。这就是声明性方法的工作原理。在 Spring 的情况下(在我的示例中),声明有更多的行并且与相应的代码具有相同的表现力。如果有这样的声明比代码短的例子 - 我想看看。
控制反转原则允许简单的单元测试,因为您可以用假的实现替换真实的实现(例如用内存中的替换 SQL 数据库)
我确实理解控制反转的好处(我更喜欢将这里讨论的设计模式称为依赖注入,因为 IoC 更通用 - 有多种控制,我们只反转其中一种 - 初始化控制) .我在问为什么有人需要编程语言以外的东西。我绝对可以使用代码用假的实现替换真实的实现。这段代码将表达与配置相同的内容——它只会用假值初始化字段。
mary = new FakeFemale();
我确实了解 DI 的好处。我不明白与配置相同的代码相比,外部 XML 配置有什么好处。我认为不应该避免编译——我每天都在编译,而且我还活着。我认为 DI 的配置是声明性方法的坏例子。如果声明一次并且以不同的方式多次使用,则声明可能很有用 - 例如 hibernate cfg,其中 bean 属性和 DB 列之间的映射用于保存、加载、构建搜索查询等。Spring DI 配置可以很容易地转换为配置代码,就像在这个问题的开头一样,不能吗?而且它仅用于 bean 初始化,不是吗?这意味着声明性方法不会在此处添加任何内容,是吗?
当我声明 hibernate 映射时,我只是给 hibernate 一些信息,它基于它工作 - 我没有告诉它做什么。在 spring 的情况下,我的声明告诉 spring 到底要做什么 - 那么为什么要声明它,为什么不直接做呢?
最后更新:
伙计们,很多答案都在告诉我有关依赖注入的信息,我知道这很好。
问题是关于 DI 配置的目的而不是初始化代码 - 我倾向于认为初始化代码更短更清晰。
到目前为止,我对我的问题的唯一答案是,当配置更改时,它可以避免重新编译。我想我应该发布另一个问题,因为这对我来说是一个很大的秘密,为什么在这种情况下应该避免编译。
【问题讨论】:
-
终于有人有勇气问这个问题了。当您的实现以牺牲(或至少降低)工具/IDE支持为代价时,为什么您确实希望避免重新编译?
-
标题好像不太对。作者说 IOC 容器很好,但似乎对使用 XML 配置而不是通过代码进行配置存在问题(而且也很公平)。我可能会建议“通过 XML 或其他非代码方法配置 IOC 容器有什么好处?”
-
@Orion 我提供的示例(包括男性和女性)不需要任何 IOC 容器。我对国际奥委会很好;使用容器是否使用 XML 配置,对我来说仍然是一个悬而未决的问题。
-
@Orion 2:虽然我在大多数项目中使用某种形式的 IOC,但其中一些从 IOC 容器中受益,与它们从变量赋值容器或 If 语句容器中受益一样多——通常语言就足够了为了我。我重新编译我正在处理的项目没有问题,并且可以方便地分离开发/测试/生产初始化代码。所以对我来说标题很好。
-
我发现样品有问题。原则上是注入服务,而不是数据
标签: xml spring dependency-injection