【问题标题】:Runtime dependency injection with Spring使用 Spring 进行运行时依赖注入
【发布时间】:2010-11-29 05:13:07
【问题描述】:

我当前的项目正在利用 Spring,我们的架构师决定让 Spring 管理服务、存储库和工厂对象,而不是域对象。我们正在密切关注领域驱动设计。不将 spring 用于域对象的原因主要是 spring 只允许静态依赖注入。我所说的静态依赖注入的意思是,依赖是在 xml 配置中指定的并且它们被“冻结”。

我可能错了,但我目前的理解是,即使我的域仅利用接口与对象进行通信,但 spring 的 xml 配置迫使我指定具体的依赖项。因此,所有具体的依赖关系都必须在部署时解决。有时,这是不可行的。我们的大多数用例都基于根据运行时数据或从最终用户收到的消息注入特定类型。

我们的大部分设计都遵循命令模式。因此,当我们收到命令时,我们想构建我们的域模型,并根据从命令收到的数据,将特定的类型集注入到我们的聚合根对象中。因此,由于 Spring 缺乏基于运行时数据构建领域模型的能力,我们不得不使用静态工厂方法、构建器和工厂模式。

如果spring对上述情况有问题,有人可以建议吗?

我可以使用 AOP 来注入依赖项,但是我没有利用 Spring 的基础架构。

【问题讨论】:

    标签: java spring command design-patterns


    【解决方案1】:

    Spring 的依赖注入/配置仅用于配置底层技术基础设施,例如数据源、事务管理、远程处理、servlet 挂载点等。

    您使用 spring 在技术 API 和您的服务之间进行路由,在这些服务中您只需编写普通的 Java 代码。让 Spring 远离你的领域模型和服务实现是一件好事。首先,您不想将应用程序的业务逻辑绑定到一个框架或让低级技术问题“泄漏”到应用程序域模型中。 Java 代码在 IDE 中比 Spring 的 XML 配置更容易修改,因此将业务逻辑保留在 Java 中可以让您更快速地交付新功能并更轻松地维护应用程序。 Java 比 Spring 的 XML 格式更具表现力,因此如果您坚持使用纯 Java,则可以更清晰地对领域概念进行建模。

    【讨论】:

    • 仅仅因为 Spring 可以做很多事情并不意味着正确的答案是让您的应用程序在所有这些事情上都使用 Spring。
    • 虽然这对于标准贫血域模型是正确的,但 IMO 可以在域驱动设计(OP 说他正在使用)中做这些事情。
    • 这个答案非常适用于(可能更适用于)具有干净的面向对象设计并将域逻辑实现为域模型对象上的方法的非贫血域模型。贫血领域模型非常不标准。它们是应该避免的
    【解决方案2】:

    我建议您阅读 Spring 文档中有关 Using AspectJ to dependency inject domain objects with Spring 的部分。

    有趣的是,您说“我可以使用 AOP 来注入依赖项,但是我没有利用 Spring 的基础架构,”考虑到 AOP 是 Spring 基础架构的核心部分。两者配合得很好。

    上面的链接允许您让 Spring 的 AOP 透明地将依赖项注入到正在创建的域对象中,而无需直接引用 Spring 基础结构(例如,使用 new 运算符)。它非常聪明,但确实需要一些深层次的类加载修补。

    【讨论】:

    • +1。然而,根据这个特定场景的复杂性,使用 FactoryBeans 代替 AOP 可能是可行的(并且更容易)。
    • 我同意,我通常不会打扰。但是,如果应用程序是硬核 DDD,那么工厂可能并不理想。
    【解决方案3】:

    Spring 的依赖注入(以及一般的依赖注入)基本上是为了将Services、Repositories 和Factories 等连接在一起。它不应该直接处理需要动态完成以响应命令等的事情,其中​​包括大多数带有域对象的东西。相反,它通过允许您连接要用于执行这些操作的对象来控制这些操作的完成方式。

    【讨论】:

    • 这让 Spring 有点卖空。它能够做到这些,只是需要更多的努力。
    猜你喜欢
    • 2011-02-06
    • 2015-03-01
    • 1970-01-01
    • 2014-10-27
    • 2011-08-04
    • 2012-01-24
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多