2017-01-04 7 views
0

Ich bin nicht in der Lage, herauszufinden, wie man einen Dienst in einen Actor injizieren.injizierenden Dienst in den Darsteller gibt NullPointerException

Ich habe mehrere Ansätze ausprobiert und denke, dass diese am besten passen sollte.

Ich denke, das Hauptproblem besteht darin, dass ich dem nachfolgenden Akteur den Websocket als Parameter zur Verfügung stelle. Wenn ich das Inject bis zur Klassensignatur-Kompilierung ausfühle, wird wegen eines Signaturkonflikts keine Kompilierung durchgeführt. Ich habe versucht, eine currying implizite Klassendeklaration hinzuzufügen, um den Dienst zu injizieren, aber das hat auch nicht geklappt.

Was soll ich tun, um es richtig zu machen?

Das Ausführen dieses Codes führt zu einer NullPointerException.

package actors 

import akka.actor._ 
import com.google.inject.Inject 
import play.api.libs.json._ 
import models._ 
import services.WeatherService 

/** 
    * Created by jbc on 28.12.16. 
    */ 
class WeatherWSActor (out: ActorRef) extends Actor { 

    @Inject() val weatherService: WeatherService = null 

    def handleMessage(msg: JsValue): JsValue = { 

    val req = msg.as[Request] 

    req match { 
     case Request("daily") => Json.toJson(weatherService.getFourDays()) 
     case Request("next") => Json.toJson(weatherService.getNextHour()) 
    } 
    } 

    override def receive: Receive = { 
    case msg: JsValue => out ! handleMessage(msg) 
    case _ => out ! "Bad Request" 
    } 

    @scala.throws[Exception](classOf[Exception]) 
    override def postStop(): Unit = { 

    } 
} 

object WeatherWSActor { 
    def props(out: ActorRef) = Props(new WeatherWSActor(out)) 
} 

Controller-Code:

class WeatherWSController @Inject() (implicit system: ActorSystem, materializer: Materializer) extends Controller { 

    def socket = WebSocket.accept[JsValue, JsValue] { request => 
    ActorFlow.actorRef(out => WeatherWSActor.props(out)); 
    } 

} 

Der Dienst wird mit diesem Modul-Code

class Module extends AbstractModule { 
    override def configure(): Unit = { 
     bind(classOf[WeatherService]).to(classOf[WeatherServiceImpl]).asEagerSingleton() 
    } 
} 

Antwort

0

Dies ist bedeckt in den documentation, aber hier ist eine Zusammenfassung eingerichtet.

Wenn Sie Ihre Schauspieler spritzen möchten, müssen Sie ein paar Dinge ändern. Zunächst einmal ist die Injektionsstelle der Konstruktor, so

class WeatherWSActor (out: ActorRef) extends Actor { 
    @Inject() val weatherService: WeatherService = null 
    // ... 
} 

class WeatherWSActor @Inject() (out: ActorRef, 
           weatherService: WeatherService) extends Actor { 
    // ... 
} 

In der Tat werden soll, wird null zu einer Scala val Zuordnung auch Ihnen Fragen gehen zu geben.

Zweitens, eine Bindung für den Schauspieler erklären, anstatt es selbst zu erstellen.

import com.google.inject.AbstractModule 
import play.api.libs.concurrent.AkkaGuiceSupport 

import actors.WeatherWSActor 

class MyModule extends AbstractModule with AkkaGuiceSupport { 
    def configure = { 
    bindActor[WeatherWSActor]("weather-actor") 
    } 
} 

Auf einer Seite beachten, werden Sie auch eine benannte Bindung für out und ändern diese erstellen müssen, um die Definition von WeatherWSActor reflektieren:

class WeatherWSActor @Inject() (@javax.inject.Named("out-actor") out: ActorRef, 
           weatherService: WeatherService) extends Actor { 
    // ... 
} 

out-actor ist je nachdem, welche Klasse Sie in eingerichtet haben das Modul, z

class MyModule extends AbstractModule with AkkaGuiceSupport { 
    def configure = { 
    bindActor[WeatherWSActor]("weather-actor") 
    bindActor[SomeOutActor]("out-actor") 
    } 
} 

Aber ...

Da bist du out bekommen, wenn ein Web-Socket erstellt wird, Sie sind (vermutlich) mehrere WeatherWSActor Instanzen haben würde. Dies wirkt sich auf die Abhängigkeitsinjektion aus, sodass es sinnvoller ist, outActor nicht zu injizieren (und daher keine Bindung dafür zu erstellen), sondern einen Singleton WeatherWSActor zu verwenden, der an alle Instanzen von OutActor sendet, die an einem bestimmten Punkt adressiert sind im Akteursystem.

Verwandte Themen