參考https://developer.lightbend.com/guides/akka-quickstart-java/define-actors.html
Messages可以是各種類型
Hello World Actors 用了三種類型
WhoToGreet:拜訪接受者
Greet:執(zhí)行拜訪的說明
Greeting : 包含拜訪的消息
定義好了Actors和Messages,需要注意下面幾點:
- 因為Messages是公共的API栅干,所以一個最佳實踐就是消息應(yīng)該有一個好的名字蛉艾,豐富的語義,特定作用域绍昂,甚至可以包括數(shù)據(jù)類型唯绍。這樣易用拼岳,容易理解,容易調(diào)試况芒。
- Messages應(yīng)該不變的惜纸,因為多個線程直接共享叶撒。
- 還有一個最佳實踐,把和actor相關(guān)聯(lián)的消息耐版,作為一個靜態(tài)類放在Actor的類中祠够。 這樣就容易理解這個Actor期望和處理哪種類型的消息。
- 還有一個常用的做法粪牲,在Actor中用靜態(tài)的props的描述如何去構(gòu)建這個Actor古瓤。
Greeter 和 Printer中使用最佳實踐
The Greeter Actor
從Greeter.java 中截取的一部分
package com.lightbend.akka.sample;
import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import com.lightbend.akka.sample.Printer.Greeting;
public class Greeter extends AbstractActor {
static public Props props(String message, ActorRef printerActor) {
return Props.create(Greeter.class, () -> new Greeter(message, printerActor));
}
static public class WhoToGreet {
public final String who;
public WhoToGreet(String who) {
this.who = who;
}
}
static public class Greet {
public Greet() {
}
}
private final String message;
private final ActorRef printerActor;
private String greeting = "";
public Greeter(String message, ActorRef printerActor) {
this.message = message;
this.printerActor = printerActor;
}
@Override
public Receive createReceive() {
return receiveBuilder()
.match(WhoToGreet.class, wtg -> {
this.greeting = message + ", " + wtg.who;
})
.match(Greet.class, x -> {
printerActor.tell(new Greeting(greeting), getSelf());
})
.build();
}
}
讓我們來分解下代碼:
- Greeter繼承了AbstractActor重寫了createReceive方法。
- Greeter構(gòu)造函數(shù)接受兩個參數(shù):String message 用于構(gòu)建Greeting message腺阳, ActorRef printerActor是處理問候結(jié)果的Actor的引用落君。
- receiveBuilder定義了對不同消息應(yīng)該有不同的反應(yīng)。一個Actor是可以有狀態(tài)的亭引。獲取和改變內(nèi)部狀態(tài)是線程安全的绎速,因為它被Actor model保護著。createReceive會按著Actor所期望的那樣去處理消息焙蚓。對于Greeter纹冤,它處理兩種Message類型,WhoToGreet和Greet购公。前者會更新Actor的greeting狀態(tài)萌京,后者會觸發(fā)發(fā)送消息到Printer Actor。
- greeting變量包含著Actor的狀態(tài)君丁,默認被設(shè)置為''
- 靜態(tài)的props方法創(chuàng)建和返回一個Props實例枫夺。 Props實例是一個創(chuàng)建Actors參數(shù)集的配置類』婷疲可以認為他是一個不變的和可以被自由分享的菜單來創(chuàng)建Actor,可以包含部署的信息较坛。這個例子印蔗,簡單傳遞用于構(gòu)建Actor所需要的參數(shù)。
Printer Actor
- 它創(chuàng)建日志通過Logging.getLogger(getContext().getSystem(), this)丑勤; 這樣后就可以通過log.info() 來寫日志华嘹。
- 它處理一種message, Greeting. 然后輸出日志。
package com.lightbend.akka.sample;
import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.event.Logging;
import akka.event.LoggingAdapter;
public class Printer extends AbstractActor {
static public Props props() {
return Props.create(Printer.class, () -> new Printer());
}
static public class Greeting {
public final String message;
public Greeting(String message) {
this.message = message;
}
}
private LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
public Printer() {
}
@Override
public Receive createReceive() {
return receiveBuilder()
.match(Greeting.class, greeting -> {
log.info(greeting.message);
})
.build();
}
}