AKKA Actor建立

Actor 類定義 

Actor 類須要繼承AbstractActorjava

實現createReceive方法,綁定各種actor收到不一樣類型消息對應處理不一樣業務邏輯api

默認提供了ReceiveBuilder類輔助建立 Receive網絡

對actorOf的調用返回ActorRef的實例。這是 Actor 實例的句柄,也是與之交互的惟一方法。併發

ActorRef是不可變的,而且與它所表示的 Actor 有一對一的關係。ActorRef也是可序列化的, 序列化經過網絡發送它,並在遠程主機上使用它,而且它仍然在網絡上表示原始節點上的同一個 Actor。app

Actor的層級關係

Actor的層級關係相似樹模式ide

誰建立誰管理原則:post

ActorSystem 建立就由ActorSystem負責監控管理(重啓,異常,恢復等)
Actor中建立另外的Actor,則建立者看作爲父級,負責監控管理它建立出來的actorui

 Actor 生命週期

 

 actorOf -> preStart -> start -> receive -> stop -> postStop

另外:spa

reRestart()默認行爲是在重啓(restarting)以前,它會終止全部的children actors(這個過程是遞歸的)。postRestart()則發生在重啓成功以後。固然,方法均可以重寫這兩個方法以改變其行爲。rest

 

Props 

Props 建立 Actor 的配置選項,推薦在actor類提供一個通用的props方法來建立

注意:

1,同一個akka集羣中建立的actor 實例 name不能重複,否則會報InvalidActorNameException異常

2,ActorSytem同一個集羣,各節點的ActorSytem name必須相同

3,不容許自行new建立actor實例
若是直接new Actor實例方式建立Actor會報ActorInitializationException錯誤

 

示例:

<!-- Gradle -->
dependencies {
  compile group: 'com.typesafe.akka', name: 'akka-actor_2.12', version: '2.5.21'
}

 

package akka.demo.actor

import akka.actor.AbstractActor
import akka.actor.ActorRef

import akka.actor.Props
import akka.japi.pf.ReceiveBuilder
import org.slf4j.LoggerFactory

/**
 ** created by tankx
 ** 2019/9/10
 **/
class HelloActor(val name: String) : AbstractActor() {

  //建立子actor
  private val childActor: ActorRef = context.actorOf(ChildActor.props())

  companion object {
    private val log = LoggerFactory.getLogger(HelloActor::class.java)
   //提供靜態通用對外的props  
    fun props(name: String): Props {
      //return Props.create(HelloActor::class.java, name)//默認方式
      return Props.create(HelloActor::class.java) {
        HelloActor(name)
      }
    }
  }

  override fun preStart() {
    log.info("preStart")
    super.preStart()
  }

  override fun postStop() {
    log.info("postStop")
    super.postStop()
  }

  override fun createReceive(): Receive {
    return ReceiveBuilder.create().matchAny(::onReceive).build()
  }

  fun onReceive(msg: Any) {

    log.info("$name say: $msg")
    log.info("sender:{}", sender.toString())


  }

}
package akka.demo.actor

import akka.actor.AbstractActor

import akka.actor.Props
import akka.japi.pf.ReceiveBuilder
import org.slf4j.LoggerFactory

/**
 ** created by tankx
 ** 2019/9/10
 **/
class ChildActor : AbstractActor() {

  private val log = LoggerFactory.getLogger(ChildActor::class.java)

  companion object {
    fun props(): Props {
      return Props.create(ChildActor::class.java)
    }
  }

  override fun preStart() {
    log.info("preStart")
    super.preStart()
  }

  override fun postStop() {
    log.info("postStop")
    super.postStop()
  }

  override fun createReceive(): Receive {
    return ReceiveBuilder.create().matchAny(::onReceive).build()
  }

  fun onReceive(msg: Any) {
    log.info("onReceive: $msg")
  }

}

 

 建立ACTOR,併發消息

val system = ActorSystem.create("akka-system")

val actorRef = system.actorOf(HelloActor.props("aa"), HelloActor::class.java.simpleName)

actorRef.tell("hi world", ActorRef.noSender()) //給actor發消息

 

 依賴注入

若是有依賴注入的狀況,須要傳入依賴項來構建Actor

示例:

package akka.demo.actor

import akka.actor.Actor
import akka.actor.IndirectActorProducer

/**
 ** created by tankx
 ** 2019/9/11
 ** 若是有依賴注入方式可以使用當前的工廠類的方式進行建立actor
 **/
class ActorFactory(var applicationContext: String) : IndirectActorProducer {


  override fun actorClass(): Class<out Actor> {
    return HelloActor::class.java
  }

  override fun produce(): Actor {
    return HelloActor(applicationContext)
  }


}

 

建立方式:

val actorFactoryRef = system.actorOf(Props.create(ActorFactory::class.java, "aaa"), "aaa")
  actorFactoryRef.tell("hi factory", ActorRef.noSender())

 

總結:

 AKKA建立Actor須要嚴格按照推薦的方式去建立,以免破壞Actor 封裝。

相關文章
相關標籤/搜索