2013-07-12 2 views
6

akka 액터로 시작된 서버의 필드 주입에 널 포인터 예외가 발생합니다.guice injection with actor가 null 포인터를 던졌습니다.

Schedular 부분 :

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 클래스 부분 :

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을 얻고있다. 이것에 대해 조언 해주세요.

감사합니다.

+0

참고. Retreiver 클래스가 액터로 생성되면 guice가 dataService를 삽입 할 것으로 기대합니다. – popcoder

답변

7

Ak32가 Guice가 아닌 Retriever 배우를 인스턴스화하기 때문에 NullPointerException이 표시됩니다. 당신은 당신의 인스턴스를 생성하고 Akka에, IndirectActorProducer는 당신이 이것을 달성 할 수 있음을 전달하는 Guice을 얻을 필요가, 예를 들면 :

produce() 는, 그것을 호출 될 때마다 새로운 Actor 인스턴스를 생성해야합니다
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); 
    } 
} 

하는 것으로 같은 인스턴스를 반환 할 수 없습니다.

그런 다음 Akka가의 RetrieverDependencyInjector을 통해 배우를 검색 할 수 있습니다 예 :

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

내가 당신에 대해 생각

더 언급 UPDATE, 당신이 GenericDependencyInjector으로 RetrieverDependencyInjector을 켤 수 있습니다 Actor 클래스를 생성자 매개 변수로 제공하면 다음과 같이 할 수 있습니다.

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

나는 이것을 시도하지 않았지만 시작점을 줄 수 있습니다. 이 필요가있는 사람들을위한

+0

조나단, 답변 해 주셔서 감사합니다. 나는 타입이없는 배우가 많이 있습니다. 그래서 나는 배우를 탐구하는데 익숙한 일반적인 의존성 인젝터가 필요하다. 내가 어떻게 할 수 있니? – popcoder

+1

@popprem 나는 나의 업데이트 된 답변을 보았다. – Jonathan

+0

고마워요 조나단, 도움이되는데. – 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); 
} 

}

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

그게 전부를 ...!

+0

어떻게 이것을 공급자 주사와 함께 사용할 수 있습니까? 일반적으로 내 GuiceModule에서 나는 다음과 같은 기능을 가지고 : '@Provides @Named ("somename") ActorRef getSomeActor() { 반환 Akka.System() ... }'문제는 내가하지 않아도됩니다 GuiceModule 내부에서 인젝터에 접근. –

+0

@Chanan'인젝터의이 같은 모듈에 주입 될 수 @Provides @Singleton @Named ("jcrActor") ActorSelection jcrActor (최종 ActorSystem 시스템 최종 인젝터 분사)를 예외 { 시스템을 던진다. actorOf (새로운 RoundRobinPool (3) .props (Props.create (GuiceInjectedActor.class, injector, JcrActor.class)), "jcrActorRouter"); return system.actorSelection (ActorConstants.PATH_JCR_ACTOR_ROUTER); } – rwijngaa

2

가, 다른 방법으로 할 수 있습니다 예를 들어, 당신은 부팅 정적 인젝터 핸들 또는 일부-인젝터 홀더 클래스를 넣을 수 있습니다, 당신이 호출에 의해 상속 방법 배우를 만들 때 주입 : 사전을 (

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

인젝터를 어떻게 주입합니까? – mor

+0

주입기는 Guice에 의해 제공되며 주입 할 필요가 없습니다. –

관련 문제