构造函数与 preStart:何时使用哪个?

问题描述 投票:0回答:1

在 Akka 中,你可以在构造函数中初始化 actor 的状态。此外,作为 actor 生命周期的一部分,可以重写

preStart
方法来初始化 actor 的状态并将被调用:

  • 当 Actor 首次启动时,在它开始处理第一条消息之前
  • 当 actor 重新启动时,除非
    postRestart
    被覆盖而不调用它

这两种方式(构造函数和

preStart
)似乎涵盖了 actor 启动阶段的重叠阶段,略有不同的是构造函数 保证 在重新启动时被调用,而
preStart
可以被跳过,前提是您覆盖
postRestart

是否有公认或记录的最佳实践或模式来说明在哪种情况下使用哪种实践或模式?

scala akka
1个回答
16
投票

来自通过构造函数初始化的文档:

使用构造函数进行初始化有很多好处。首先,它使得可以使用

val
字段来存储在 Actor 实例生命周期内不会改变的任何状态,从而使 Actor 的实现更加健壮。当调用
actorOf
创建 Actor 实例以及重新启动时,会调用构造函数,因此 Actor 的内部始终可以假设发生了正确的初始化。

来自 通过 preStart 初始化的文档:

actor 的方法

preStart()
仅在第一个实例初始化期间(即创建其
ActorRef
时)直接调用一次。在重新启动的情况下,从
preStart()
调用
postRestart()
,因此,如果不覆盖,每次重新启动时都会调用
preStart()
。但是,通过重写
postRestart()
,可以禁用此行为,并确保只有一次对
preStart()
的调用。

此模式的一个有用用法是在重新启动期间禁止为子级创建新的

ActorRefs
。这可以通过覆盖
preRestart()
来实现。

如果您希望在每次实例化 Actor 时进行初始化(包括重新启动:重新启动时,将创建底层 Actor 的新实例),请通过构造函数使用初始化。示例场景是在创建 Actor 时使用不变状态。 如果您希望仅在创建 Actor 的第一个实例时进行初始化

,请通过

preStart 使用初始化并覆盖 postRestart

 以不调用 
preStart
。示例用例是在重新启动时保留子 Actor(默认情况下,
preRestart
 会停止 Actor 的子级,这就是文档提到在此示例用例中覆盖 
preRestart
 的原因)。
	

© www.soinside.com 2019 - 2024. All rights reserved.