Play! FrameworkをScalaに1年近く使っています。私は現在、バージョン2.5.xを使用しています。Play Frameworkで@SingletonをScalaのオブジェクトよりも使うのはなぜですか?
私はPlayのコントローラーの進化と、開発者がどのように静的なルートobject
を離れてしまったのかを知っています。
私はまた、Guiceの使用状況を知っています。
あなたがactivatorをダウンロードして実行する場合:
activator new my-test-app play-scala
をアクティベーターはあなたのためのテンプレートプロジェクトを生成します。 私の質問は、具体的にそのテンプレートのthisファイルです。
私のテストアプリ/アプリ/サービス/ Counter.scala
package services
import java.util.concurrent.atomic.AtomicInteger
import javax.inject._
/**
* This trait demonstrates how to create a component that is injected
* into a controller. The trait represents a counter that returns a
* incremented number each time it is called.
*/
trait Counter {
def nextCount(): Int
}
/**
* This class is a concrete implementation of the [[Counter]] trait.
* It is configured for Guice dependency injection in the [[Module]]
* class.
*
* This class has a `Singleton` annotation because we need to make
* sure we only use one counter per application. Without this
* annotation we would get a new instance every time a [[Counter]] is
* injected.
*/
@Singleton
class AtomicCounter extends Counter {
private val atomicCounter = new AtomicInteger()
override def nextCount(): Int = atomicCounter.getAndIncrement()
}
またthisファイルにその使用状況を見ることができます:
私のテストアプリ/アプリ/コントローラ/CountController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import services.Counter
/**
* This controller demonstrates how to use dependency injection to
* bind a component into a controller class. The class creates an
* `Action` that shows an incrementing count to users. The [[Counter]]
* object is injected by the Guice dependency injection system.
*/
@Singleton
class CountController @Inject() (counter: Counter) extends Controller {
/**
* Create an action that responds with the [[Counter]]'s current
* count. The result is plain text. This `Action` is mapped to
* `GET /count` requests by an entry in the `routes` config file.
*/
def count = Action { Ok(counter.nextCount().toString) }
}
これは、構築物を持つすべてのコントローラを意味@Inject() (counter: Counter)
にはCounter
の同じインスタンスが送信されます。
だから私の質問は次のとおりです。
この例のためにあなただけのScalaのオブジェクトを使用することができるときなぜ、コントローラに@Singleton
、その後@Inject
それを使うのか?
コードが大幅に少なくなっています。
例:
私のテストアプリ/アプリ/サービス/ Counter.scala
package services
trait ACounter {
def nextCount: Int
}
object Counter with ACounter {
private val atomicCounter = new AtomicInteger()
def nextCount(): Int = atomicCounter.getAndIncrement()
}
ので、同じようにそれを使用します。
私のテストアプリ/アプリ/コントローラ/ CountController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import services.{Counter, ACounter}
/**
* This controller demonstrates how to use dependency injection to
* bind a component into a controller class. The class creates an
* `Action` that shows an incrementing count to users. The [[Counter]]
* object is injected by the Guice dependency injection system.
*/
@Singleton
class CountController extends Controller {
//depend on abstractions
val counter: ACounter = Counter
def count = Action { Ok(counter.nextCount().toString) }
}
違いは何ですか?注射が好まれているのはなぜですか?
パラメータを渡す必要がないかどうかは関係ありませんしかし、そうした場合、guiceが依存関係をインスタンス化して注入するためのクラスにする必要があります。 –