Grailsのサービスについて
Takahiro Sugiura:
sugiura.takahiro@cij.co.jp
Grailsのサービスとは
●Grailsのサービスは、アプリケー ションロジックの大半を置く場所。
●再利用と関心の分離が上手くい かないので、コントローラの中に アプリケーションロジックを置くの はよくない。
サービスを利用するコード例
class BookController {
// BookServiceのBeanをインジェクション def bookService
def search = {
// 条件に応じて本を検索する def searchResult =
bookSearvice.searchBook( params ) ...
} }
サービスのインジェクション
インジェクト先のプロパティ名に、 サービスのクラス名の「プロパ
ティ名表現」を使う。
例) BookServiceをインジェクショ ンしたい場合、bookServiceプロ パティを宣言する。
サービスのインジェクション
サービスをインジェクションできる のはコントローラだけでなく、タグ リブにも、ドメインにも、別のサー ビスにもインジェクションできる。
サービスのコード例
class BookService {
def scope = “prototype” def transactional = true def searchBook( params ) {
// 条件に応じて本を検索する
def criteria = Book.createCriteria() ...
} }
スコープの宣言
スコープ(scope)はインスタンスの ライフサイクルを指定するもので、
prototype request flash
flow
conversation session
singleton(デフォルト)
がある。
トランザクションの宣言
transactionalはトランザクション 中での実行を指定する。
trueを指定した場合、トランザク
ションの中でサービスのメソッドを 実行する。
falseを指定した場合、トランザク ションとは関係なくサービスのメ ソッドを実行する。
インジェクションのコード
コントローラにサービスをインジェ クションしているのは、
ControllersGrailsPlugin.groovy になる。
インジェクションのコード
// コントローラクラスのBean定義
"${grailsClass.fullName}"("${grailsClass.fullName}Proxy":
"newInstance") {bean →
bean.singleton = singleton
// autowiringの設定。名前による参照解決。 bean.autowire = "byName"
}
コントローラに宣言したプロパティ 名に応じたBeanを、名前により
解決し、インジェクションする。
サービスプラグインのコード
サービスのプラグインのソースは、 ServicesGrailsPlugin.groovy
になる。
サービスプラグインのコード
def props = new Properties()
props."*"="PROPAGATION_REQUIRED"
トランザクションの振る舞いを設定 する。サービスのすべてのメソッド ("*")に対して
、"PROPAGATION_REQUIRED" (常にトランザクションがある状態) を指定。
サービスプラグインのコード
"${serviceClass.propertyName}"(TransactionProxyFactoryBean) { bean ->
宣言的トランザクションを行うサー ビスのBean定義を行う。
宣言的トランザクションとは、トラン ザクションの管理をロジックから分 離し、外部で行う方式。
おわりに
サービスは、SpringのDI、AOP、 宣言的トランザクション、といった 機能を上手く使って、適度なバラ ンスで動作する。