2013-07-12 23 views
6

null işaretçisi atar Akka aktör olarak başlatılan bir sunucunun alan enjeksiyonu üzerine boş işaretçi istisnası alıyorum.oyuncu ile guice enjeksiyonu kullanarak

Schedular kısmı:

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()); 

} 

Retreiver sınıfı kısmı:

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()) { 
    .... 
    .... 
    .... 
    } 

}

Ben DataService için boş alıyorum. Lütfen bana bu konuda tavsiyede bulunun.

Teşekkürler.

+0

not. Retreiver sınıfı bir oyuncu olarak oluşturulduğunda veriService'nin enjekte edilmesini bekliyorum. – popcoder

cevap

7

Akka, Retriever aktörünü değil Guice'yi başlattığınız için NullPointerException alıyorsunuz. Eğer örneğini oluşturmak ve sonra Akka için, IndirectActorProducer bunu elde yardımcı olabilir geçmek Guice almak gerekir, örneğin:

produce() zahmete çağrılır her zaman yeni bir Actor örneğini oluşturmalısınız
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); 
    } 
} 

Not olduğunu aynı örneği geri dönemez.

Ardından Akka, RetrieverDependencyInjector aracılığıyla aktör almak için alabilirsiniz mesela:

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

seni düşündüm

fazla yorum GÜNCELLEME, bir GenericDependencyInjector içine RetrieverDependencyInjector çevirmek mümkün olabilir Actor sınıfının bir yapıcı parametresi olarak olmasını sağlayarak, belki de aşağıdaki gibi bir şey yapmanıza izin verir:

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

Bunu denemedim, ancak size bir başlangıç ​​noktası verebilir. Bu ihtiyaç duyan herkes için

+0

Jonathan, Cevabınız için teşekkürler. Çok değişken oyuncularım var. Bu yüzden, oyuncuları geri almak için kullanılacak genel bir bağımlılık enjektörüne ihtiyacım var. Bunu nasıl yapabilirim? – popcoder

+1

@popprem Bir fikrim vardı, güncellenmiş cevabımı görün. – Jonathan

+0

Teşekkürler Jonathan, bu yararlı. – popcoder

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); 
} 

}

VE

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

sne bunu ... !!!

+0

Bunu sağlayıcı enjeksiyonla birlikte nasıl kullanabilirsiniz? Normalde benim GuiceModule içinde böyle işlevi vardır: '@Provides @Named ("somename") ActorRef getSomeActor() { dönüş Akka.System() ... }' Sorun yok olmasıdır GuiceModule içinden Enjektöre erişim. –

+0

@Chanan 'Enjektör de bu gibi, modül içine enjekte edilebilir: @Provides @Singleton @Named ("jcrActor") ActorSelection jcrActor (nihai ActorSystem sistemi olup, son Enjektör enjektörün) özel durum { sistemi atar. actorOf (yeni RoundRobinPool (3) .props (Props.create (GuiceInjectedActor.class, enjektör, JcrActor.class)), "jcrActorRouter"); return system.actorSelection (ActorConstants.PATH_JCR_ACTOR_ROUTER); } ' – rwijngaa

2

Orada, başka yollar olabilir, örneğin sen Boot statik enjektör kolu veya bazı-Enjektör-Tutucu-sınıfı koyabilirsiniz ve çağrı miras yöntemini aktör oluştururken enjekte Ön çalıştırma (

)
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()) { 
     .... 
     .... 
     .... 
     } 
    } 

ve ayrıca, aynı zamanda UntypedActorFactory bir kapsamda enjektör tarafından aktörü başlatmak için aktör sağlayıcısı enjektörü enjekte edebilir ve asla bunun için herhangi bağlamalar yok

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; 
    } 
} 
+0

Enjektörü nasıl enjekte edersiniz? – mor

+0

Enjektör, Guice tarafından sağlanır, enjekte edilmesine gerek yoktur. –