从Java使用become()

时间:2013-02-04 12:05:10

标签: java akka

我正在使用Java中的Akka。根据文档, context.become() Procedure<Object>作为参数。事实上,它期望 PartialFunction<Object, BoxedUnit> 这似乎是一些自动生成的东西,其中包含很多带有奇怪名称的方法。

从Java使用成为()的正确方法是什么?

PS   我正在使用Akka 2.0.3

更新: 看起来有两种方法:context()和getContext()。第一个返回ActorContext,第二个返回UntypedActorContext。 UntypedActorContext有become(Procedure<Object>)

3 个答案:

答案 0 :(得分:8)

您对Akka Java和Scala API感到困惑。从技术上讲,你可以从Java代码中使用像Akka这样的Scala库,但通常它冗长而繁琐。因此,Akka团队决定开发单独的API - 原生于Scala和Java适配器。

在Scala API中,您扩展akka.actor.Actor,其中context字段的类型为akka.actor.ActorContext。此ActorContext.become()接受PartialFunction,这是特定于Scala的类。

另一方面,在Java API中,您使用(类似Java)方法getContext()扩展akka.actor.UntypedActor,返回akka.actor.UntypedActorContext。这个接受akka.japi.Procedure

简而言之 - 如果您使用的是Java API,请坚持下去。 Scala和Java文档之间有明显的区别。

答案 1 :(得分:0)

在java中有很多关于如何做到这一点的好例子。希望这个例子有用:

Procedure<Object> angry = new Procedure<Object>() {
@Override
public void apply(Object message) {
  if (message.equals("bar")) {
    getSender().tell("I am already angry?", getSelf());
  } else if (message.equals("foo")) {
    getContext().become(happy);
  }
}
};

Procedure<Object> happy = new Procedure<Object>() {
@Override
public void apply(Object message) {
  if (message.equals("bar")) {
    getSender().tell("I am already happy :-)", getSelf());
  } else if (message.equals("foo")) {
    getContext().become(angry);
  }
 }
};

public void onReceive(Object message) {
if (message.equals("bar")) {
  getContext().become(angry);
} else if (message.equals("foo")) {
  getContext().become(happy);
} else {
  unhandled(message);
}

} }

答案 2 :(得分:0)

结帐this! 一切都可以像在Scala中一样完成。

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
                        context.become(withCounter(counter + 1))
                    }
                    is Decrement -> // another change of actor state
                        context.become(withCounter(counter - 1))
                    else -> unhandled(cmd)
                }
            }
            .build()
}

这是Kotlin,但使用Java API,因此Java代码类似...