从给定的@inject class实例化一个val
Instantiate a val from a given @inject class
如何从这个 class 实例化一个对象?我有另一个 class,我想在其中使用下面定义的 MongoUtils
class。这个class来自reactivemongo
package controllers
import javax.inject.Inject
import scala.concurrent.Future
import play.api.Logger
import play.api.mvc.{ Action, Controller }
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.functional.syntax._
import play.api.libs.json._
// Reactive Mongo imports
import reactivemongo.api.Cursor
import play.modules.reactivemongo.{ // ReactiveMongo Play2 plugin
MongoController,
ReactiveMongoApi,
ReactiveMongoComponents
}
// BSON-JSON conversions/collection
import reactivemongo.play.json._
import play.modules.reactivemongo.json.collection._
/*
* Example using ReactiveMongo + Play JSON library.
*
* There are two approaches demonstrated in this controller:
* - using JsObjects directly
* - using case classes that can be turned into JSON using Reads and Writes.
*
* This controller uses JsObjects directly.
*
* Instead of using the default Collection implementation (which interacts with
* BSON structures + BSONReader/BSONWriter), we use a specialized
* implementation that works with JsObject + Reads/Writes.
*
* Of course, you can still use the default Collection implementation
* (BSONCollection.) See ReactiveMongo examples to learn how to use it.
*/
class MongoUtils @Inject() (val reactiveMongoApi: ReactiveMongoApi)
extends Controller with MongoController with ReactiveMongoComponents {
/*
* Get a JSONCollection (a Collection implementation that is designed to work
* with JsObject, Reads and Writes.)
* Note that the `collection` is not a `val`, but a `def`. We do _not_ store
* the collection reference to avoid potential problems in development with
* Play hot-reloading.
*/
def collection: JSONCollection = db.collection[JSONCollection]("persons")
def index = Action { Ok("works") }
def create(name: String, age: Int) = Action.async {
val json = Json.obj(
"name" -> name,
"age" -> age,
"created" -> new java.util.Date().getTime())
collection.insert(json).map(lastError =>
Ok("Mongo LastError: %s".format(lastError)))
}
def createFromJson = Action.async(parse.json) { request =>
import play.api.libs.json.Reads._
/*
* request.body is a JsValue.
* There is an implicit Writes that turns this JsValue as a JsObject,
* so you can call insert() with this JsValue.
* (insert() takes a JsObject as parameter, or anything that can be
* turned into a JsObject using a Writes.)
*/
val transformer: Reads[JsObject] =
Reads.jsPickBranch[JsString](__ \ "firstName") and
Reads.jsPickBranch[JsString](__ \ "lastName") and
Reads.jsPickBranch[JsNumber](__ \ "age") reduce
request.body.transform(transformer).map { result =>
collection.insert(result).map { lastError =>
Logger.debug(s"Successfully inserted with LastError: $lastError")
Created
}
}.getOrElse(Future.successful(BadRequest("invalid json")))
}
def findByName(name: String) = Action.async {
// let's do our query
val cursor: Cursor[JsObject] = collection.
// find all people with name `name`
find(Json.obj("name" -> name)).
// sort them by creation date
sort(Json.obj("created" -> -1)).
// perform the query and get a cursor of JsObject
cursor[JsObject]()
// gather all the JsObjects in a list
val futurePersonsList: Future[List[JsObject]] = cursor.collect[List]()
// transform the list into a JsArray
val futurePersonsJsonArray: Future[JsArray] =
futurePersonsList.map { persons => Json.arr(persons) }
// everything's ok! Let's reply with the array
futurePersonsJsonArray.map { persons =>
Ok(persons)
}
}
}
到目前为止我已经尝试了 val mongoutil = new MongoUtils(reactiveMongoApi = play.modules.reactivemongo)
但显然它不起作用。
如果您从控制器使用此 class,您应该按如下方式注释您的控制器,以便播放器向其中注入一个实例:
class MyController @Inject() (mongoUtils: MongoUtils) extends Controller {}
如果你没有使用注入控制器,你可以通过注入器访问它:
Play.current.injector.instanceOf(classOf[MongoUtils])
在此处阅读有关依赖注入的更多信息:https://www.playframework.com/documentation/2.4.x/ScalaDependencyInjection
您可以使用 Play 的依赖注入机制来解析作为 MongoDB 接口的 ReactiveMongoApi 实例。步骤可以是:
将下面的行添加到 application.conf
play.modules.enabled += "play.modules.reactivemongo.ReactiveMongoModule"
play.modules.enabled += "modules.CommonModule"
modules.CommonModule 是您定义绑定的地方,这样 Guice,一个与 Play 2.4 集成的 DI 框架,知道要为特定接口使用哪个实现.例如,
package modules
import com.google.inject.AbstractModule
import dao.impl.UserDaoMongo
import dao.UserDao
import play.api.{Configuration, Environment}
import services.{UserService, UserServiceImpl}
case class CommonModule(environment: Environment, configuration: Configuration) extends AbstractModule {
def configure() {
bindDAOs()
bindServices()
}
private def bindDAOs(): Unit = {
bind(classOf[UserDao]).to(classOf[UserDaoMongo])
}
def bindServices(): Unit = {
bind(classOf[UserService]).to(classOf[UserServiceImpl])
}
}
此外,将控制器设置为单例是一种很好的做法。例如:
import javax.inject.{Singleton, Inject}
@Singleton
class UserController @Inject()(userService: UserService) extends Controller {
请阅读本文以了解如何将 Reactivemongo 与 Play 框架一起使用。另一方面,这是一个完整的例子:https://github.com/luongbalinh/play-mongo
如何从这个 class 实例化一个对象?我有另一个 class,我想在其中使用下面定义的 MongoUtils
class。这个class来自reactivemongo
package controllers
import javax.inject.Inject
import scala.concurrent.Future
import play.api.Logger
import play.api.mvc.{ Action, Controller }
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.functional.syntax._
import play.api.libs.json._
// Reactive Mongo imports
import reactivemongo.api.Cursor
import play.modules.reactivemongo.{ // ReactiveMongo Play2 plugin
MongoController,
ReactiveMongoApi,
ReactiveMongoComponents
}
// BSON-JSON conversions/collection
import reactivemongo.play.json._
import play.modules.reactivemongo.json.collection._
/*
* Example using ReactiveMongo + Play JSON library.
*
* There are two approaches demonstrated in this controller:
* - using JsObjects directly
* - using case classes that can be turned into JSON using Reads and Writes.
*
* This controller uses JsObjects directly.
*
* Instead of using the default Collection implementation (which interacts with
* BSON structures + BSONReader/BSONWriter), we use a specialized
* implementation that works with JsObject + Reads/Writes.
*
* Of course, you can still use the default Collection implementation
* (BSONCollection.) See ReactiveMongo examples to learn how to use it.
*/
class MongoUtils @Inject() (val reactiveMongoApi: ReactiveMongoApi)
extends Controller with MongoController with ReactiveMongoComponents {
/*
* Get a JSONCollection (a Collection implementation that is designed to work
* with JsObject, Reads and Writes.)
* Note that the `collection` is not a `val`, but a `def`. We do _not_ store
* the collection reference to avoid potential problems in development with
* Play hot-reloading.
*/
def collection: JSONCollection = db.collection[JSONCollection]("persons")
def index = Action { Ok("works") }
def create(name: String, age: Int) = Action.async {
val json = Json.obj(
"name" -> name,
"age" -> age,
"created" -> new java.util.Date().getTime())
collection.insert(json).map(lastError =>
Ok("Mongo LastError: %s".format(lastError)))
}
def createFromJson = Action.async(parse.json) { request =>
import play.api.libs.json.Reads._
/*
* request.body is a JsValue.
* There is an implicit Writes that turns this JsValue as a JsObject,
* so you can call insert() with this JsValue.
* (insert() takes a JsObject as parameter, or anything that can be
* turned into a JsObject using a Writes.)
*/
val transformer: Reads[JsObject] =
Reads.jsPickBranch[JsString](__ \ "firstName") and
Reads.jsPickBranch[JsString](__ \ "lastName") and
Reads.jsPickBranch[JsNumber](__ \ "age") reduce
request.body.transform(transformer).map { result =>
collection.insert(result).map { lastError =>
Logger.debug(s"Successfully inserted with LastError: $lastError")
Created
}
}.getOrElse(Future.successful(BadRequest("invalid json")))
}
def findByName(name: String) = Action.async {
// let's do our query
val cursor: Cursor[JsObject] = collection.
// find all people with name `name`
find(Json.obj("name" -> name)).
// sort them by creation date
sort(Json.obj("created" -> -1)).
// perform the query and get a cursor of JsObject
cursor[JsObject]()
// gather all the JsObjects in a list
val futurePersonsList: Future[List[JsObject]] = cursor.collect[List]()
// transform the list into a JsArray
val futurePersonsJsonArray: Future[JsArray] =
futurePersonsList.map { persons => Json.arr(persons) }
// everything's ok! Let's reply with the array
futurePersonsJsonArray.map { persons =>
Ok(persons)
}
}
}
到目前为止我已经尝试了 val mongoutil = new MongoUtils(reactiveMongoApi = play.modules.reactivemongo)
但显然它不起作用。
如果您从控制器使用此 class,您应该按如下方式注释您的控制器,以便播放器向其中注入一个实例:
class MyController @Inject() (mongoUtils: MongoUtils) extends Controller {}
如果你没有使用注入控制器,你可以通过注入器访问它:
Play.current.injector.instanceOf(classOf[MongoUtils])
在此处阅读有关依赖注入的更多信息:https://www.playframework.com/documentation/2.4.x/ScalaDependencyInjection
您可以使用 Play 的依赖注入机制来解析作为 MongoDB 接口的 ReactiveMongoApi 实例。步骤可以是:
将下面的行添加到 application.conf
play.modules.enabled += "play.modules.reactivemongo.ReactiveMongoModule"
play.modules.enabled += "modules.CommonModule"
modules.CommonModule 是您定义绑定的地方,这样 Guice,一个与 Play 2.4 集成的 DI 框架,知道要为特定接口使用哪个实现.例如,
package modules
import com.google.inject.AbstractModule
import dao.impl.UserDaoMongo
import dao.UserDao
import play.api.{Configuration, Environment}
import services.{UserService, UserServiceImpl}
case class CommonModule(environment: Environment, configuration: Configuration) extends AbstractModule {
def configure() {
bindDAOs()
bindServices()
}
private def bindDAOs(): Unit = {
bind(classOf[UserDao]).to(classOf[UserDaoMongo])
}
def bindServices(): Unit = {
bind(classOf[UserService]).to(classOf[UserServiceImpl])
}
}
此外,将控制器设置为单例是一种很好的做法。例如:
import javax.inject.{Singleton, Inject}
@Singleton
class UserController @Inject()(userService: UserService) extends Controller {
请阅读本文以了解如何将 Reactivemongo 与 Play 框架一起使用。另一方面,这是一个完整的例子:https://github.com/luongbalinh/play-mongo