如何将自定义Executor注入播放应用程序?

问题描述 投票:0回答:2

我已经通过play-akka配置文件为数据库操作分配了一个专用线程池。现在我正在使用actor系统注入需要此线程池的服务并访问执行上下文。

 public class ServiceA{

     final Executor executionContext;

     @Inject
     public ServiceA(ActorSystem system) {
        this.executionContext = system.dispatchers().lookup("akka.actor.db-context");
 }

但这使得测试ServiceS变得困难。我想做的只是直接注入Executor,如下所示:

 public class ServiceA{

     final Executor executionContext;

     @Inject
     public ServiceA(Executor dbExecutionCtx) {
        this.executionContext = dbExecutionCtx;
 }

我该如何实现这一目标?我已经尝试创建一个guice模块来注入Executor但它错误地抱怨没有启动的应用程序,并且当它执行它绑定类时无法访问ActorSystem。

java akka playframework-2.4 playframework-2.5
2个回答
1
投票

我使用一种模式,我可以在任何我想要的地方获得EC。我在Singleton中创建了一个ActorSystem并将其注入我的服务中。

我有一个使用ActorSystems,Dispatchers的设计以及更多用于监控的设计。看看这个,看看你是否可以整合它。

因此,如果将MyActorSystem注入到您的班级,您可以从中访问EC。看看MyDispatcher和EC的使用:

@Singleton
public class MyActorSystem implements IMyActorSystem{

    ActorSystem system;
    public MyActorSystem() {
        system = ActorSystem.create();

    }

    public ActorRef create() {
        final ActorRef actor = system.actorOf(
                Props.create(MyWorker.class).withDispatcher("my-disp")
        );
        return actor;
    }

    public void shutdown(){
        system.shutdown();
    }

    public ExecutionContextExecutor getDispatcher(){
        return system.dispatcher();
    }
    }

    public class MyDispatcher implements IMyDispatcher {

    MyActorSystem system;

    @Inject public MyDispatcher(MyActorSystem system) {
        this.system = system;
    }


    public CompletableFuture<Object> dispatch(final Object story) {
        List<CompletableFuture<Object>> futureList = new ArrayList<>();
        final ActorRef actor = system.create();
        final CompletableFuture<Object> completed = FutureConverter
                .fromScalaFuture(Patterns.ask(actor, story, 50000)).executeOn(system.getDispatcher())
                .thenApply(i -> (Object) i);
        return completed;
    }

    public ExecutionContextExecutor getDispatcher(){
        return system.getDispatcher();
    }
}

0
投票

从2.6开始播放其默认调度程序的DI绑定,如下所示:

bind[ExecutionContextExecutor].toProvider[ExecutionContextProvider],
bind[ExecutionContext].to[ExecutionContextExecutor],
bind[Executor].to[ExecutionContextExecutor],

ExecutionContextProvider在哪里

@Singleton
class ExecutionContextProvider @Inject() (actorSystem: ActorSystem) extends Provider[ExecutionContextExecutor] {
  def get = actorSystem.dispatcher
}

看起来Play不会在DI绑定中暴露其他命名的调度程序,因此您可以使用@Named绑定以相同的方式自行完成。还可以编写Play DI模块,该模块将动态地将所有命名的akka​​调度程序公开为对应的命名绑定。

© www.soinside.com 2019 - 2024. All rights reserved.