2017-04-16 63 views
1

有什麼方法可以在Scala對象中注入play數據庫依賴關係?我知道我們可以做類似注入數據庫依賴關係scala對象

class MyClass @Inject() (db: Database) = { 
} 

但我想注入依賴關係,而實際上沒有使用Play插件。

我build.sbt看起來像這樣

scalaVersion := "2.11.8" 

lazy val sparkVersion = "2.1.0" 

lazy val hadoopVersion = "2.7.0" 

lazy val jacksonVersion = "2.8.7" 

libraryDependencies ++= Seq(
    "org.apache.spark" %% "spark-core" % sparkVersion, 
    "org.apache.spark" %% "spark-sql" % sparkVersion, 
    "org.apache.hadoop" % "hadoop-common" % hadoopVersion, 
    "com.databricks" %% "spark-csv" % "1.5.0", 
    "org.codehaus.janino" % "janino" % "3.0.7", 
    "com.databricks" % "spark-redshift_2.11" % "3.0.0-preview1", 
    "com.amazonaws" % "aws-java-sdk-s3" % "1.11.34", 
    "com.typesafe" % "config" % "1.3.1", 
    "com.typesafe.play" % "play-json_2.11" % "2.4.6", 
    "com.typesafe.play" %% "play" % "2.5.9", 
    "com.typesafe.play" % "play-jdbc_2.11" % "2.5.14", 
    "com.amazon.redshift" % "jdbc42" % "1.2.1.1001" from "https://s3.amazonaws.com/redshift-downloads/drivers/RedshiftJDBC42-1.2.1.1001.jar" 
) 

fork in Test := true 

assemblyMergeStrategy in assembly := { 
    case ".gitkeep" => MergeStrategy.discard 
    case "META-INF/groovy-release-info.properties" => MergeStrategy.discard 
    case "META-INF/MANIFEST.MF" => MergeStrategy.discard 
    //case "log4j.properties" => MergeStrategy.deduplicate 
    case x: String if x.matches("""META-INF/.*\.(SF|DSA|RSA)""") => MergeStrategy.discard 
    case x: String if x.startsWith("META-INF/services/org.apache.lucene") => MergeStrategy.concat 
    case x => MergeStrategy.first 
} 

我試圖

object MyObject { 
@Inject() 
var db: Database = _ 
} 

,但它不能爲空指針異常

+0

從我的卑微經驗:通常你不想在'對象'中存儲狀態。因此,您不希望注入狀態來以其他方式反對,而不僅僅是在方法調用中傳遞它。這樣你就沒有初始化問題,沒有任何問題改變注入依賴和行爲的行爲仍然是可測試的。 –

回答

2

@Inject不會在這種情況下工作。 Object在語言級別上作爲單例使用,而依賴注入是由配置驅動的,在Playframework的情況下,使用底層的Guice引擎構建。有效的DI只適用於由DI創建或插入其中的對象,因此Guice應該至少知道MyObject的存在。

最佳選擇是使用類@Inject註釋

case class MyObject @Inject() (db: Database) 

如果不是這種情況,你可以從應用程序對象Injector引用(這是棄用,應避免使用)

object MyObject { 
    lazy val db: Database = Play.unsafeApplication.injector.instanceOf[Database] 
} 
+0

正如你所說的那樣,當我使用Injector時,它會引發錯誤,因爲「應用程序未啓動」 – hlagvankar

+0

您需要運行一個應用程序。 val db之前你有懶嗎? – mavarazy

+0

是的。實際上它是沒有Play插件的Spark應用程序。但是我想使用Play特定的功能,如注入數據庫,配置來讀取application.conf,Environment等,而不需要在build.sbt中啓用Play插件。到目前爲止閱讀application.conf我正在使用ConfigFactory I/O配置。有沒有什麼方法可以在不使用Play插件的情況下使用它們? – hlagvankar