この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Playframework 2.4でDIする
Playframework 2.4における最大の変更点といえば、DI(依存性注入)をデフォルトで使用できるようになったことだと思います。 ※JSR 330をベースに実装
Playでは静的なDIと動的なDI、どちらも使用できるようになっていますが、 今回は動的なDIの方法について紹介します。
動作環境
今回使用した動作環境は以下のとおりです。 * OS : MacOS X 10.9.4 * Java : 1.8.0_11 * Playframework : 2.4.2
サンプルアプリ作成
まずはactivatorコマンドをつかって、プロジェクトのひな形を作成します。 テンプレートの種類はplay-scalaにしましょう。
% activator new runtime-di-sample
・
・
runコマンドで起動確認できたら準備完了です。
プログラム修正
DIを使用するにはroutesGeneratorに「InjectedRoutesGenerator」が指定されている必要があるので まずはbuild.sbtを確認しましょう。
routesGenerator := InjectedRoutesGenerator
次に、DI対象のclass(とtrait)を定義します。
package samples
import javax.inject._
import play.api.inject._
import scala.concurrent._
import play.api._
trait Person {
def write()
}
@Singleton
class Programmer extends Person {
def write(): Unit = {
Logger.debug("writing program!!!")
}
}
ここではPersonというtraitを定義し、それを実装するProgrammerクラスを定義しました。 また、ここでは@Singletonというアノテーションを使用していますが、これを指定することで 対象のクラスが自動的にシングルトンになります。
次に、DIされるコンポーネントのバインド設定をします。 Playではモジュールを使用してカスタムバインディングの設定をするため、 下記のようなモジュールを作成します。
package modules
import samples._
import com.google.inject.AbstractModule
import play.api._
class HelloModule extends AbstractModule {
def configure() = {
bind(classOf[Person])
.to(classOf[Programmer])
}
}
ここではPersonトレイトにProgrammerクラスをバインドしてます。 モジュールを定義したら、conf/application.confでモジュールの設定を記述します。
play.modules.enabled += "modules.HelloModule"
これでアプリ起動時にモジュールがロードされます。
最後にコントローラでDIしましょう。 @Injectアノテーションで引数にPersonを指定します。
import samples._
import javax.inject.Inject
import play.api._
import play.api.mvc._
class Application @Inject()(p:Person) extends Controller {
def index = Action {
//DIされたオブジェクトを実行
p.write()
Ok(views.html.index("Your new application is ready."))
}
}
アプリを起動してブラウザでアクセスしてみてください。 Person(実装はProgrammer)がDIされてメソッド実行できることがわかります。
まとめ
今回はPlay2.4のRuntime Dependency Injectionを試してみました。 ちなみにApplicationLoaderを使用して静的DIをする方法もこちらにあるので、ご確認ください。