Мій код:
Global.scala - я просто налаштував його так під час запуску, він надсилає акторові швидке повідомлення. виняток кинуто звідси; я перевірив, що введені послуги завантажено.
object Global extends GlobalSettings {
override def onStart(app: Application): Unit = {
val system = app.actorSystem
system.actorOf(TempActor.props, TempActor.name) ! "hi hi"
}
}
TempActor.scala
package actors
class TempActor @Inject() (
@Named(TestServiceModuleNames.RedisService) redisService: StatusService
, @Named(TestServiceModuleNames.DynamoDbService) dynamoDbService: StatusService
) extends Actor with ActorLogging {
override def receive: Receive = {
case msg: Any =>
log.info(s"the msg => $msg")
context.system.shutdown()
}
}
object TempActor extends NamedActor {
override def name: String = this.getClass.getSimpleName
override def props: Props = Props[TempActor]
}
TestServiceModule.scala - модуль guice для завантаження в сервісах, які потрібні акторові, я обов’язково ввімкнув модуль у застосунку .conf
package modules
class TestServiceModule extends AbstractModule with AkkaGuiceSupport {
val configs = ConfigFactory.load()
override def configure(): Unit = {
bind(classOf[StatusService]).annotatedWith(Names.named(TestServiceModuleNames.RedisService)).toInstance(new RedisStatusServiceImpl(new RedisConfig(configs.getString("redis.host"), configs.getInt("redis.port"))))
bind(classOf[StatusService]).annotatedWith(Names.named(TestServiceModuleNames.DynamoDbService)).toInstance(new DynamoDBStatusServiceImpl(Region.US_EAST_1, configs.getString("dynamo.db.endpoint"), configs.getString("dynamo.db.table.name.status")))
}
}
object TestServiceModuleNames {
final val RedisService = "RedisStatusService"
final val DynamoDbService = "DynamoDbStatusService"
}
application.conf
redis.host="localhost"
redis.port=4242
dynamo.db.endpoint="http://localhost:8000"
dynamo.db.table.name.status="status"
play.modules {
enabled += "modules.TestServiceModule"
}
play.akka.actor-system="warden"
akka {
loggers = ["akka.event.slf4j.Slf4jLogger"]
loglevel = "DEBUG"
}
Моє завдання - мати ігровий додаток з бекендом, який обробляється акторами. Кожен актор буде мати певні залежності від різних служб, я намагався вводити ці служби за допомогою Google Guice.
Все, що я отримую під час запуску програми, це трасування винятків:
java.lang.IllegalArgumentException: no matching constructor found on class actors.TempActor for arguments []
Я не знаю, як саме це виправити ...
Я використовую Play 2.4.
Відповіді:
5 за відповідь № 1Лінія override def props: Props = Props[TempActor]
намагається викликати конструктор нульових аргументівверсія TempActor, де жодна не існує. У коді Akka за Props немає нічого, що б дозволило йому зрозуміти, що ви використовуєте Google Guice, і відповідно створити TempActor.
Ви можете зробити це, наприклад:
override def props: Props = Props[TempActor] = {
Injector injector = Guice.createInjector(new TestServiceModule());
Props(injector.getInstance(TempActor.class))
}
2 для відповіді № 2
Врешті-решт, я пішов із тим, що, на мою думку, працювало.
Я використовував код пластини котла в https://github.com/rocketraman/activator-akka-scala-guice генерувати акторів, які мали залежності.
У самому додатку Play я "не використовую систему акторів / уявлення, яку вбудував Play, я створюю власну систему інжекторів та акторів у глобальних налаштуваннях.
object Global extends GlobalSettings {
final val injector = Guice.createInjector(
new ServiceModule(),
new ConfigModule(),
new AkkaModule(),
new ActorModule()
)
final val actorSystem = injector.instance[ActorSystem]
final val quartzScheduler = QuartzSchedulerExtension.get(actorSystem)
final val configs = new ConfigProvider().get()
override def onStart(app: Application): Unit = {
// onstart logic
}
override def onStop(app: Application): Unit = {
actorSystem.shutdown()
}
}
Те, як я створив свій проект, має головнеактор / супервізор, який генерується звичайним способом за допомогою "actorSystem.actorOf (..., name)". Мій керівник не має ніяких залежностей, оскільки його робота полягає в тому, щоб приймати запити та передавати їх відповідному дочірньому актору (які створюються за допомогою коду rocketraman).