简而言之,在使用 时Java API
,请确保您正在调用getContext()
方法而不是context()
打算与 一起使用的方法Scala API
。
签出这个(java)
@Slf4j
@RequiredArgsConstructor
public class Greeter extends AbstractActor {
private final ActorRef printer;
public static Props props(ActorRef printer) {
return Props.create(Greeter.class, printer);
}
@Override
public Receive createReceive() {
return withWhomToGreet(""); // initial state
}
private Receive withWhomToGreet(String name) {
return receiveBuilder()
.match(WhoToGreet.class, // changing actor state context
whoToGreet -> getContext().become(withWhomToGreet(whoToGreet.getWho())))
.match(Greet.class, greet -> {
String msg = format("Hola, %s", name);
log.info("sending {} to {}", msg, printer);
printer.tell(Greeting.of(msg), self());
})
.matchAny(o -> {
log.error("unexpected: {}", o);
unhandled(o);
})
.build();
}
}
或者这个(科特林)
class CounterActor : AbstractActor() {
companion object Factory {
sealed class Commands {
override fun toString(): String = javaClass.simpleName
object Increment : Commands()
object Decrement : Commands()
object GetState : Commands()
}
private val type = CounterActor::class.java
val props: Props = Props.create(type) { CounterActor() }
val name: String = type.simpleName
}
override fun createReceive(): Receive = withCounter(0) // init state
private fun withCounter(counter: Int): Receive =
receiveBuilder()
.matchAny { cmd ->
context.system.log().info("current: $counter, received: $cmd")
when (cmd) {
is GetState -> sender.tell("counter value: $counter", self)
is Increment -> {
// switch context with new updated actor state,
// actor is still stateless, similarly like we
// doing in scala for context.become
// Make sure with Java API you are calling
// getContext() method, not context()!
context.become(withCounter(counter + 1))
}
is Decrement -> // another change of actor state
context.become(withCounter(counter - 1))
else -> unhandled(cmd)
}
}
.build()
}
一切都可以用与 Scala 中相同的想法来完成