当前位置: 首页 > 知识库问答 >
问题:

如何使“CustomExecutionContext”可用于Play 2.6控制器中的依赖项注入?

储峻
2023-03-14

我跟随播放2.6的Scala留档和创建非阻塞操作的示例代码,并遇到一些运行时问题。我已经使用Scala模板创建了一个新的Play应用程序(sbt new playframe/play-scala-种子. g8)。

播放留档建议应该在新的控制器中工作的代码是(这段代码逐字取自播放留档页面,从我这里有一些额外的导入):

// some imports added by me to get the code to compile
import javax.inject.Inject
import scala.concurrent.ExecutionContext
import scala.concurrent.Future

import akka.actor.ActorSystem
import play.api.libs.concurrent.CustomExecutionContext
import play.api.mvc._
import play.api.mvc.ControllerComponents
// end imports added by me

import play.api.libs.concurrent.CustomExecutionContext

trait MyExecutionContext extends ExecutionContext

class MyExecutionContextImpl @Inject()(system: ActorSystem)
  extends CustomExecutionContext(system, "my.executor") with MyExecutionContext

class HomeController @Inject()(myExecutionContext: MyExecutionContext, val controllerComponents: ControllerComponents) extends BaseController {
  def index = Action.async {
    Future {
      // Call some blocking API
      Ok("result of blocking call")
    }(myExecutionContext)
  }
}

然后,根据使用其他线程池的文档,我定义了my。执行器应用程序中的线程池。conf我的应用程序文件:

my.executor {
  fork-join-executor {
    parallelism-factor = 20.0
    parallelism-max = 200
  }
}

我应该注意,我不想使用默认执行上下文,因为我想在单独的上下文中运行futures,该上下文可能用于有限的资源,如数据库连接池。

所有这些都可以通过sbt compile进行编译。但是,当我使用sbt run运行此应用程序并在web浏览器中访问我的应用程序时,会出现以下错误:

CreationException:无法创建喷油器,请参阅以下错误:

1) 没有控制器的实现。MyExecutionContext已绑定。在定位控制器时。控制器的第一个参数的MyExecutionContext。新控制器。(NewController.scala:17)查找控制器时。路由器第二个参数的新控制器。路线。(斯卡拉:29)在玩。应用程序编程接口。注射RouteProvider$。bindingsFromConfiguration(BuiltinModule.scala:121):绑定(类router.Routes to self)(通过模块:com.google.inject.util.modules$OverrideModule)-

我过去使用过Play 2.3,并且知道当您定义对象的实例(通过@Singleton或模块)时,依赖注入是有效的;然而,Play 2.6在DI上的留档表明“Guice能够自动实例化任何类的构造函数上带有@Inject,而不必显式绑定它。这个被称为准时绑定的特性在Guice留档中有更详细的描述。"

我的问题是:我需要向Play自己的示例中添加哪些特定的代码行或配置来实现这一点,为什么?


共有1个答案

平学
2023-03-14

在进一步阅读Scala依赖项注入文档页面的绑定注释部分时,我发现了一个可能的解决方案。它特别指出:

将实现绑定到接口的最简单方法是使用Guice@实现通过注释。

因此,通过将其添加到myMyExecutionContexttrait,如下所示:

import com.google.inject.ImplementedBy

@ImplementedBy(classOf[MyExecutionContextImpl])
trait MyExecutionContext extends ExecutionContext

MyExecutionContextImpl的一个实例被实例化并正确注入控制器。

太糟糕了,这个@ImplementedBy注释没有列在非阻塞操作文档的示例代码中!

 类似资料:
  • 有没有可能使控制器依赖于他们的服务,而不是通过使用服务容器,而是通过纯粹的构造函数依赖注入? 我希望以这种方式编写控制器: 不幸的是,正如我所看到的,Symfony ControllerResolver不通过ServiceContainer而是通过简单的调用创建新的控制器实例。

  • 问题内容: 我仍然是Angularjs的新手。我想在控制器中动态注入服务(我创建的)的依赖项。 但是,当我对具有依赖项的服务进行编码时,出现此错误: 错误:未知提供程序:$ windowProvider <-$ window <-base64 这是控制器的代码。 此代码有效: 此代码不起作用: 另一个问题是服务与控制器位于同一模块中。如果模块具有依赖项,则无法使用(我的模块配置中具有$ route

  • 目前我有一个MVC应用程序,它也包含WebApi控制器。 我已经设置了StructureMap来使用默认约定进行初始化,该约定处理MVC和WebApi的服务依赖关系。这一切都完美无缺。 但是,我有一个应该为 WebAPI 注入的身份验证服务依赖项,并为 MVC 注入不同的实现。由于 StructureMap 具有相同的初始化引导代码,因此如何根据传入的请求是 WebAPI 终结点还是 Mvc 控制

  • 此时,我正在轻松地将东西注入控制器,在某些情况下构建自己的ResolversServices类。生活是美好的。 我不知道如何让框架自动注入到非控制器类中。工作原理是让框架自动注入我的控制器,这实际上是我项目的配置: 我在想我是否能为自己的课程做同样的事情。当我模仿控制器时,我假设我很接近,就像这样: 我想我失败的地方是当我这样叫它的时候: 我跟踪这个的问题实际上是所有关于DI的内容都是在控制器级别

  • 问题内容: 我阅读了一些带有基本示例的春季教程,并且对如何正确整理内容有些困惑。 麻烦在于,我想使用应用程序上下文来提取单例控制器引用,但是我读过其他一些主题,除非绝对必要,否则不应直接访问应用程序上下文。我想我应该使用构造函数实例化我想要的引用,但是在这里事情对我来说变得很模糊。 我有几个fxml文件的javafx应用程序。我有一个主要的fxml,其他主要是动态加载到main内部。 我将使用简化

  • 问题内容: 如何在不使用调用的情况下使用Spring将依赖项注入? 问题答案: 由于Servlet 3.0 ServletContext具有“ addListener”方法,因此可以通过如下代码添加而不是在web.xml文件中添加侦听器: 这意味着你可以正常地注入“ MyHttpSessionListener”中,并且,只要你的应用程序上下文中存在bean,就会使侦听器注册到容器中