参考https://developer.lightbend.com/guides/akka-quickstart-java/define-actors.html
Messages可以是各种类型
Hello World Actors 用了三种类型
-
WhoToGreet:拜访接受者
-
Greet:执行拜访的说明
-
Greeting : 包含拜访的消息
定义好了Actors和Messages,需要注意下面几点:
- 因为Messages是公共的API,所以一个最佳实践就是消息应该有一个好的名字,丰富的语义,特定作用域,甚至可以包括数据类型。这样易用,容易理解,容易调试。
- Messages应该不变的,因为多个线程直接共享。
- 还有一个最佳实践,把和actor相关联的消息,作为一个静态类放在Actor的类中。 这样就容易理解这个Actor期望和处理哪种类型的消息。
- 还有一个常用的做法,在Actor中用静态的props的描述如何去构建这个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构造函数接受两个参数:String message 用于构建Greeting message, ActorRef printerActor是处理问候结果的Actor的引用。
- receiveBuilder定义了对不同消息应该有不同的反应。一个Actor是可以有状态的。获取和改变内部状态是线程安全的,因为它被Actor model保护着。createReceive会按着Actor所期望的那样去处理消息。对于Greeter,它处理两种Message类型,WhoToGreet和Greet。前者会更新Actor的greeting状态,后者会触发发送消息到Printer Actor。
- greeting变量包含着Actor的状态,默认被设置为''
- 静态的props方法创建和返回一个Props实例。 Props实例是一个创建Actors参数集的配置类。可以认为他是一个不变的和可以被自由分享的菜单来创建Actor,可以包含部署的信息。这个例子,简单传递用于构建Actor所需要的参数。
Printer Actor
- 它创建日志通过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();
}
}
网友评论