【问题标题】:Mutability and Spring可变性和弹簧
【发布时间】:2013-07-30 22:48:39
【问题描述】:

我目前在一家大量使用 Spring Dependency Injection 的商店工作时正在重新阅读“Effective Java”。在阅读 Bloch 的书时,人们不禁会想起他对类中不变性的强调(他多次声明类应该尽可能不可变)。我不禁感到这与 Spring Dependency Injection(以及大多数 DI 引擎)对 javabeans 标准的依赖直接冲突。 阅读“Spring in Action”中关于 DI 的章节似乎会让 Bloch 畏缩,因为它们的可变类由在您的权限范围之外实例化的对象组成,这些对象本身可能是可变的。

是不是 Bloch 的想法对 Spring 来说太新奇了? Spring模型被破坏了吗? Bloch 关于不变性的立场是否仅适用于编写库代码?在编写 Spring 代码时,我应该编写具有大量 getter 和 setter 的灵活对象还是将所有内容加载到构造函数中?

【问题讨论】:

  • 布洛赫没有说“永远不要让事情变得可变”,他说“不要让他们变得比必要的更可变”。如果您的框架需要一定程度的可变性,那么这就是您必须忍受的。
  • 在关于可变性、伸缩构造函数和构建器模式的项目中,他有点破坏了 javabeans 标准(将其称为过时),但该标准是 Spring 的基础,这是否意味着春天过时了吗?
  • spring 不依赖 javabeans 标准。
  • books.google.com/… - 抱歉链接。如果您阅读本文,您会发现“Spring 使用 JavaBeans 规范来形成其 DI 配置模型的核心”的引用。第 4 页第 3 段
  • 我编辑了上面的帖子。在我放置 MVC 的所有地方,我的意思是 DI

标签: java spring immutability


【解决方案1】:

事实上,spring bean 在思想上是不可变的,即使你没有强制执行。

您只能为通过构造函数注入初始化的 final 字段提供 getter。

通常您不这样做,但您永远不应该重新分配由 DI 框架注入的 bean 的字段。这是因为除了它们的依赖项(并且它们的范围是单例的)之外,spring bean 通常不持有任何状态。当然,也有一些例外,例如原型和请求范围的 bean,它们很少见(例如,在 2 个大项目和 2 个中型项目中,我只使用了 1 个原型范围的 bean)

【讨论】:

  • 我同意:大多数 Spring 实例化的对象都是“单例”而不是真正的“可变”(服务、daos、控制器、transactionManagers ......)。
  • 如果我将一个可变对象注入到 final 字段中,但不会阻止该对象发生变化,从而导致对象图脆弱
  • @nsfyn55 注入什么对象完全取决于您。它与 DI 无关。
  • 当然可以,但是是什么让我免受可变性错误的影响,例如将同一个实例注入几个类、修改一些底层成员以及破坏所有其他持有该实例的成员的状态。我知道你会说“好吧,不要那样做”,但是那里有很多不正当的程序员,而且 Bloch 似乎依靠防御性复制之类的东西来缓解这些类型的问题。
  • 对于不存储状态的单例 bean。这是大多数情况
【解决方案2】:

如果您使用基于构造函数的注入,您可以保持类不可变并且仍然使用依赖注入。这样您就可以避免不必要的设置器。

【讨论】:

    【解决方案3】:

    我自己没有看到冲突,尤其是 Spring MVC。 Spring管理哪些bean?主要是你的控制器和你的服务/数据层你的 DAO 和服务。无论如何,这些通常没有真实状态,也没有设置器。如果您的问题在于 setter 注入(例如,您有自己的类需要由 Spring 管理,并且您不想为某些字段设置 setter),那么您可以改用构造函数注入(或两者结合)。

    【讨论】:

      猜你喜欢
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-08
      • 2018-09-08
      • 1970-01-01
      • 2017-09-12
      相关资源
      最近更新 更多