How to create a Scala/Akka Actor whose constructor requires arguments

This is an excerpt from the Scala Cookbook. This is Recipe 13.2, “How to create a Scala/Akka Actor whose constructor requires arguments.”

Problem

You want to create an Akka actor in a Scala application, and you want your actor’s constructor to have one or more arguments.

Solution

Create the actor using the syntax shown here, where HelloActor takes one constructor parameter:

val helloActor = system.actorOf(Props(new HelloActor("Fred")), name = "helloactor")

Discussion

When creating an actor whose constructor takes one or more arguments, you still use the Props class to create the actor, but with a different syntax than when creating an actor whose constructor takes no arguments.

The following code demonstrates the difference between creating an actor with a no-args constructor and an actor that takes at least one constructor parameter:

// an actor with a no-args constructor
val helloActor = system.actorOf(Props[HelloActor], name = "helloactor")

// an actor whose constructor takes one argument
val helloActor = system.actorOf(Props(new HelloActor("Fred")), name = "helloactor")

To demonstrate these differences, the following source code is a modified version of the example in Recipe 13.1. Comments are included in the code to highlight the changes:

import akka.actor._

// (1) constructor changed to take a parameter
class HelloActor(myName: String) extends Actor {
    def receive = {
        // (2) println statements changed to show the name
        case "hello" => println(s"hello from $myName")
        case _       => println(s"'huh?', said $myName")
    }
}

object Main extends App {
    val system = ActorSystem("HelloSystem")
    // (3) use a different version of the Props constructor
    val helloActor = system.actorOf(Props(new HelloActor("Fred")), name = "helloactor")
    helloActor ! "hello"
    helloActor ! "buenos dias"
    system.shutdown
}

As shown in this example, if your actor takes more than one argument, include those arguments in the constructor call. If the HelloActor constructor required both a first and last name, you’d specify them like this:

Props(new HelloActor("John", "Doe")), name = "helloactor")

Remember that an actor instance is instantiated and started when the actorOf method is called, so the only ways to set a property in an actor instance are:

  • By sending the actor a message
  • In the actor’s constructor
  • In its preStart method

You’ve already seen how to send a message to an actor and use its constructor. The preStart method is demonstrated in Recipe 13.4, “Understanding the Methods in the Akka Actor Life Cycle”.