【问题标题】:Non-managed objects in Spring application (best practice)Spring 应用程序中的非托管对象(最佳实践)
【发布时间】:2016-01-16 18:50:14
【问题描述】:

我最近一直在研究一些 Web 应用程序和 REST Web 服务(Spring IoC/MVC/Data JPA 等)。它们通常遵循相同的模式:控制器类 --> 服务类(自动装配了几个“实用程序”/业务逻辑类)--> Spring Data Repositories。

上面几乎所有的类都是 Spring 单例。我觉得这会使类中的代码和某些功能更脏;例如,我不能在一个类中有一个状态,我需要在方法之间传递很多参数,而且我真的不喜欢超过 1-2 个参数(虽然我知道有时这是必要的)。

我想知道如何在大型(例如企业)类型的应用程序中克服这个问题。

  • 在 Spring 应用程序中使用非 Spring 托管类是一种常见的做法吗?如果是这样,您如何将依赖项传递给它(通常会自动装配的那些)?例如,如果我使用构造函数注入,那么我需要将所有必要的依赖项自动连接到创建对象的类中,我想避免这种情况。此外,我真的不想在加载时间编织等方面搞乱,以便将 bean 自动装配到非 Spring 对象中。
  • 使用原型作用域 bean 是一个好的解决方案吗?唯一的事情是我需要使用 AOP 的作用域代理(或方法注入等)来确保我首先为任何自动装配到单例中的 bean 获得一个新实例。这是一个“干净”且可靠的选择(即,确定不会存在并发类型的问题)吗?我仍然可以毫无问题地将任何单例自动装配到这些类中吗?

是否有人在大型系统上工作(并且实际上设法保持结构不“臃肿”和干净)有任何建议吗?也许有一些我不知道但可以使用的模式?

任何帮助表示赞赏。

【问题讨论】:

  • “类中不能有状态”是什么意思?一般来说,基础设施位被认为是“设置”状态,在 bean 实例化时设置,但在其生命周期内保持不变。
  • 我的意思是我不能在 Spring 单例中包含实例变量,因为据我所知它们不是线程安全的。
  • 使用实例变量是非常安全和习惯的;查看任何 Spring 教程(包括官方入门指南)。只要在启动时配置好一切,就没有线程问题。
  • 可能有几种方法可以做到这一点。一种是自定义作用域,另一种是使用对象来表示要处理的事物,这些对象封装了所有需要的状态,并且可能具有对服务的引用,或者可以注入服务。对于第一种方法,我发现尝试DIY-DI 来了解什么是自定义范围非常有用。第二种方法(在我看来)是使用double dispatch pattern 的结果。
  • @Augusto 看起来整个问题是对bean生命周期误解的结果;最简单的方法(使用在启动期间初始化的实例变量)非常好。

标签: java spring oop


【解决方案1】:

Spring 设计得很好,您不必担心 DI 的 IoC 实现。您提到的 /Controller Layer -> Service Layer -> Data Access Layer/ 的模式在实践中很好,并且这些单例对象由于 OOP 规则而没有状态是可以的:“将对象视为服务提供者做好一件事”。模型可以将状态作为 JPA 单元用于在数据库中存储某些内容。不是强制性的,在大型系统中,您将有脏代码,您提到如何传递大量参数,这仅取决于您的设计决策,需要更深入的构造。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    相关资源
    最近更新 更多