Roy*_*Lin 2 playframework playframework-2.4
我正在将我的应用从2.3播放到2.4.
在我的GlobalSettings中的2.3应用程序中,我不得不使用光滑访问数据库来创建postgres数据库功能.
由于GlobalSettings在2.4中已弃用,因此替代方法是使用Eager Bindings:
https://www.playframework.com/documentation/2.4.x/ScalaDependencyInjection#Eager-bindings
像这样:
class MyModule extends AbstractModule {
def configure() = {
db.withSession { implicit ss =>
StaticQuery.update("""CREATE OR REPLACE FUNCTION ... """).execute
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这给了我错误:
java.lang.ExceptionInInitializerError:
core.includes$.<init>(includes.scala:14)
core.includes$.<clinit>(includes.scala)
Application$$anonfun$configure$1.apply(Application.scala:17)
Application$$anonfun$configure$1.apply(Application.scala:15)
scala.slick.backend.DatabaseComponent$DatabaseDef$class.withSession(DatabaseComponent.scala:34)
scala.slick.jdbc.JdbcBackend$DatabaseFactoryDef$$anon$4.withSession(JdbcBackend.scala:61)
modules.jdbc.Database$$anonfun$withSession$1.apply(Database.scala:14)
modules.jdbc.Database$$anonfun$withSession$1.apply(Database.scala:14)
Application.configure(Application.scala:15)
com.google.inject.AbstractModule.configure(AbstractModule.java:62)
com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:340)
com.google.inject.spi.Elements.getElements(Elements.java:110)
com.google.inject.util.Modules$OverrideModule.configure(Modules.java:177)
com.google.inject.AbstractModule.configure(AbstractModule.java:62)
com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:340)
com.google.inject.spi.Elements.getElements(Elements.java:110)
com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:138)
com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:104)
com.google.inject.Guice.createInjector(Guice.java:96)
com.google.inject.Guice.createInjector(Guice.java:73)
com.google.inject.Guice.createInjector(Guice.java:62)
play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:126)
play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:93)
play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
Run Code Online (Sandbox Code Playgroud)
有没有人知道如何解决这个问题?谢谢.
小智 6
根据https://www.playframework.com/documentation/2.4.2/GlobalSettings的报价收录:
GlobalSettings.beforeStart和GlobalSettings.onStart:启动时需要发生的任何事情现在都应该发生在依赖注入类的构造函数中.当依赖注入框架加载它时,类将执行其初始化.如果您需要急切初始化(因为您需要在实际启动应用程序之前执行某些代码),请定义一个急切的绑定.
如您所见,只有在应用程序启动之前需要发生某些事情时才能使用急切绑定,这在您的情况下不适用,因为db.withSession需要启动的应用程序上下文.这就是异常发生的原因(严格来说,顺便提一下,你没有以适当的方式使用急切绑定).
那你怎么能实现这个目标呢?答案在引文的前两句中.
首先,您必须定义如下内容:
@Singleton
class DatabaseService {
db.withSession { implicit ss =>
StaticQuery.update("""CREATE OR REPLACE FUNCTION ... """).execute
}
}
Run Code Online (Sandbox Code Playgroud)
然后,如果您将DatabaseService注入另一个单例类(您最好将其注入另一个单例类,或者可以多次调用代码),并且后面的类由Guice初始化,则DatabaseService的构造函数中的代码是调用(因为数据库服务首先由Guice初始化为后一个类的依赖项).
例如,您可以将其注入控制器:
@Singleton
class Application @Inject() (dbService: DatabaseService) extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
}
Run Code Online (Sandbox Code Playgroud)
然后,如果有人访问索引页面,您的代码将被执行.
编辑:
我在主题上发现了另一个stackoverflow帖子,请看这里:PlayFramework 2.4在应用程序启动后运行一些代码.它确定了应用程序启动后运行代码的正确方法,同时仍然使用急切绑定.:)
如果您依赖于ActorSystem,只需将actorSystem:ActorSystem注入到您的类中,如下所示:
@Singleton
class QuartzSchedulerService @Inject() (configuration: Configuration,
actorSystem: ActorSystem,
@Named("library.actors.ApiExecutionRecorderRouter") apiExecutionRecorderRouter: ActorRef
) {
val scheduler = QuartzSchedulerExtension(actorSystem)
scheduler.schedule("QuartzSchedulerTest", apiExecutionRecorderRouter, "Start")
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4227 次 |
| 最近记录: |