播放2.5什么是akka.stream.Materializer有用吗?

Sci*_*ion 16 scala playframework

我最近开始使用Play 2.5,我想知道做以下事情的目的是什么:

@Inject() (implicit val mat: Materializer)
Run Code Online (Sandbox Code Playgroud)

我有几段代码没有工作,并且由于这个问题解决了这个问题,但我仍然没有看到这个代码正在做什么.

谢谢

Mat*_*aun 30

物化意味着产生图表的结果

物化器使actor执行图形以生成这些结果.

最简单形式的图形由提供元素的源和消耗元素的接收器组成.

这是一个提供一系列整数的源(在本例中,整数是我们的元素):

val source = Source(1 to 10)
Run Code Online (Sandbox Code Playgroud)

这里是一个汇总,它汇总了从源获得的所有整数:

val sink = Sink.fold[Int, Int](0)(_ + _)
Run Code Online (Sandbox Code Playgroud)

我们连接源和接收器以获取图形:

val graph = source.toMat(sink)(Keep.right)
Run Code Online (Sandbox Code Playgroud)

请注意,在创建图形时,不会执行任何计算(在我们的示例中).代码是声明性的,图形描述了我们如何转换数据,但实际执行计算是其他人的工作:图形是蓝图.

现在,物化器怎么样?当我们运行图表时,物料化器会采取措施:

implicit val materializer = ActorMaterializer()
val futureResult = graph.run()
Run Code Online (Sandbox Code Playgroud)

当我们run()使用图形时,物化器采用图形并使actor执行图形中指定的数据转换; 在这个例子中,那是添加整数.

将图形想象成建造房屋的蓝图,作为工头查看蓝图的材料,告诉建筑商如何根据蓝图实际建造房屋可能会有所帮助.这个类比中的建造者对应于阿卡的演员.

您现在可以使用几个代码的原因是,使用Materializer,您可以提供执行图形的方法.图表在Akka HTTP中大量使用,Play用于HTTP请求和响应.

您在评论中提到的WSClient使用图表来执行其请求,因此需要一个物化器.


以下是创建和运行图表的完整示例:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Keep, Sink, Source}

object Graphs extends App {

  // The start of our simple graph. It provides elements, integers in our case
  val source = Source(1 to 10)

  // The end of our graph. It processes the source's elements
  val sink = Sink.fold[Int, Int](0)(_ + _)

 /*
  * Connect source and sink.
  * Keep only the output values (i.e., the graph's right side).
  * Note that this is declarative: no result is computed until we run the graph.
  */
  val graph = source.toMat(sink)(Keep.right)

  // The system coordinates actors and provides threads for them
  implicit val actorSystem = ActorSystem()
  // The materializer makes actors execute graphs
  implicit val materializer = ActorMaterializer()

  // Running the graph means that the materializer assigns actors to execute
  // the graph from start (source) to end (sink)
  val futureResult = graph.run()

  // Use the actor system's execution context, which provides threads,
  // to print the result of running the graph
  implicit val executionContext = actorSystem.dispatcher
  futureResult.foreach(res => println(s"Result of running the graph: $res"))

  actorSystem.terminate().foreach(_ => println("System is shut down"))
}
Run Code Online (Sandbox Code Playgroud)

把它放在你的代码中build.sbt可以使Akka的流库可用:

libraryDependencies += "com.typesafe.akka" %% "akka-stream" % "2.5.19"
Run Code Online (Sandbox Code Playgroud)

这里有关于源和汇的更多信息.