6

akka アクターとして起動されたサーバーのフィールド インジェクションで null ポインター例外が発生します。

スケジュールされた部分:

private ActorRef myActor = Akka.system().actorOf(
        new Props(Retreiver.class));

@Override
public void onStart(Application app) {
    log.info("Starting schedular.....!");
    Akka.system()
            .scheduler()
            .schedule(Duration.create(0, TimeUnit.MILLISECONDS),
                    Duration.create(30, TimeUnit.MINUTES), myActor, "tick",
                    Akka.system().dispatcher());

}

レトリーバークラスの部分:

public class Retreiver extends UntypedActor {

private Logger.ALogger log = Logger.of(Retreiver .class);

@Inject
private myDataService dataService;

@Override
public void onReceive(Object arg0) throws Exception {

    if (0 != dataService.getDataCount()) {
    ....
    ....
    ....
    }

}

dataService で null を取得しています。これについて私にアドバイスしてください。

ありがとう。

4

3 に答える 3

8

これが必要な人のために:

public class GuiceInjectedActor implements IndirectActorProducer {

final Injector injector;
final Class<? extends Actor> actorClass;

public GuiceInjectedActor(Injector injector, Class<? extends Actor> actorClass) {
    this.injector = injector;
    this.actorClass = actorClass;
}

@Override
public Class<? extends Actor> actorClass() {
    return actorClass;
}

@Override
public Actor produce() {
    return injector.getInstance(actorClass);
}

}

Akka.system().actorOf(Props.create(GuiceInjectedActor.class, INJECTOR,Retreiver.class))

それでおしまい...!!!

于 2013-07-16T18:40:28.493 に答える
7

NullPointerExceptionAkka がRetrieverGuice ではなくアクターをインスタンス化しているため、 が得られます。Guice を取得してインスタンスを構築し、それを Akka に渡す必要があります。IndirectActorProducerこれを実現するのに役立ちます。たとえば、次のようになります。

class RetrieverDependencyInjector implements IndirectActorProducer {
    final Injector injector;

    public RetrieverDependencyInjector(Injector injector) {
        this.injector = injector;
    }

    @Override
    public Class<? extends Actor> actorClass() {
        return Retriever.class;
    }

    @Override
    public Retriever produce() {
        return injector.getInstance(Retriever.class);
    }
}

呼び出されるたびに新しいインスタンスを作成するproduce() 必要があることに注意してください。同じインスタンスを返すことはできません。Actor

その後、Akka に を介してアクターを取得させることができます。次にRetrieverDependencyInjector例を示します。

ActorRef myActor = Akka.system().actorOf(
    Props.create(RetrieverDependencyInjector.class, injector)
);

アップデート

さらにコメントすることを考えました。必要なクラスをコンストラクターパラメーターとして提供することで、次のようなことができるようになる可能RetrieverDependencyInjector性があります。GenericDependencyInjectorActor

Props.create(GenericDependencyInjector.class, injector, Retriever.class)

私はこれを試していませんが、出発点になるかもしれません。

于 2013-07-12T10:14:55.107 に答える
2

他の方法もあります。たとえば、Boot または Some-Injector-Holder-class に静的インジェクター ハンドルを置き、継承されたメソッド preStart () を呼び出してアクターを作成するときに注入することができます。

public class Retreiver extends UntypedActor {

    private Logger.ALogger log = Logger.of(Retreiver .class);

    @Override
    public void preStart () {
        super.preStart ();
        Boot.injector.injectMembers (this);
        //Some-Injector-holder.injectMembers (this);
    }

    @Inject
    private myDataService dataService;

    @Override
    public void onReceive(Object arg0) throws Exception {

        if (0 != dataService.getDataCount()) {
        ....
        ....
        ....
        }
    }

また、アクター プロバイダーにインジェクターを挿入して、UntypedActorFactory のスコープでインジェクターによってアクターを初期化することもできます。

public class InjectingActorProvider implements Provider<ActorRef> {
    @Inject
    private Injector injector;

    @SuppressWarnings("serial")
    @Override
    public final ActorRef get() {
            Props props = new Props(new UntypedActorFactory() {
                @Override
                public Actor create() {
                    return injector.getInstance(actorClass);
                }
            });

            props = props.withRouter(...);
            props = props.withDispatcher(...);
            actor = system.actorOf(props, actorName);
            return actor;
    }
}
于 2013-08-05T08:48:25.160 に答える