如何将自定义 Executor 注入到 play 应用程序中?
Posted
技术标签:
【中文标题】如何将自定义 Executor 注入到 play 应用程序中?【英文标题】:How do I inject a custom Executor into a play application? 【发布时间】:2016-06-14 01:20:56 【问题描述】:我已经通过 play-akka 配置文件为数据库操作分配了一个专用线程池。现在,我正在向参与者系统注入需要此线程池的服务并访问执行上下文。
public class ServiceA
final Executor executionContext;
@Inject
public ServiceA(ActorSystem system)
this.executionContext = system.dispatchers().lookup("akka.actor.db-context");
但这使得测试 ServiceA 变得很困难。我想做的只是像这样直接注入 Executor:
public class ServiceA
final Executor executionContext;
@Inject
public ServiceA(Executor dbExecutionCtx)
this.executionContext = dbExecutionCtx;
我如何实现这一目标?我尝试创建一个 guice 模块来注入 Executor,但它错误地抱怨没有启动的应用程序并且在绑定类时无法访问 ActorSystem。
【问题讨论】:
【参考方案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();
【讨论】:
这也是我最终所做的。现在您必须调用 getDispatcher() 之类的方法,但它是一种改进的解决方案。我试图探索是否有其他方法可以直接注入执行程序而无需任何额外的方法调用。【参考方案2】:Play 自 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 调度程序动态公开为相应的命名绑定。
【讨论】:
以上是关于如何将自定义 Executor 注入到 play 应用程序中?的主要内容,如果未能解决你的问题,请参考以下文章
在 Play JPA 项目中使用 sbt-native-packager 将自定义文件夹添加到 Docker
将自定义JAR库添加到Android项目时Delphi10.2中的编译器错误