문제

I have the following basic setup:

public static void main(...) {
  final MyWebServiceClient client = new MyWebServiceClient(...,....,....);
  ...
  final ActorRef master = system.actorOf(Props.create(Level1Actor.class), "level1");
  master.tell(new Level1Message()...);
}

Level1Actor.onRecieve() creates several Level2Actors:

...
getContext().actorOf(Props.create(Level2Actor.class)).tell(new Level2Message(), getSelf());
...

and similarly Level2Actor.onReceive creates several Level3Actors

Here's my question: In Level3Actor.onRecieve() I want to use the web service client I created in my main method, something like:

public void onReceive() {
...
EmailSummary summary = client.getEmailSummary(username, password, etc, etc);
//create and send a response to sender based on 'summary'
...
}

How do I achieve this? Ideally I want to configure my web service at startup (urls etc) and then access it several layers of Actor deep?

Is there a way in my main method to register some factory that is called whenever an actor is created? like:

system.register(Level3Actor.class, myFactoryWithReferenceToWebService);

? Or from a Spring point of view my web service would be a bean and just be autowired into the Level3Actor instances?

Thanks.

도움이 되었습니까?

해결책

Use an Extension. They are a nice way to provide "global" stuff to actors:

public class MyWebServiceExtension extends
  AbstractExtensionId<MyWebServiceExtension.MyWebServiceExt> {

  public static MyWebServiceExtension MyWebServiceExtProvider = 
    new MyWebServiceExtension();

  public MyWebServiceExt createExtension(ExtendedActorSystem system) {
    return new MyWebServiceExt();
  }

  public static class MyWebServiceExt implements Extension {
    private final MyWebServiceClient client = new MyWebServiceClient();

    public MyWebServiceClient getClient() { return client; }
  }
}

Then in your actor:

import static com.foo.MyWebServiceExtension.MyWebServiceExtProvider;

public class MyUntypedActor extends UntypedActor {
  final MyWebServiceClient client =
    MyWebServiceExtProvider.get(getContext().system()).getClient();

Or if you are using Spring you can use the IndirectActorProducer and let Spring DI your dependencies into your actors. See this project for an example.

다른 팁

Two possible solutions are:

  1. Define the webservice ref as a property of your message classes (Level1Message, Level2Message, etc..) and propagate it down the chain via message passing.
  2. Define your actors that need the webservice as having a constructor that accepts the webservice as an arg. Then, when creating those actors, use the Props.create that accepts constructor args like so:

    getContext().actorOf(Props.create(Level2Actor.class, client))
    
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top