PlayのCacheAPIをサブプロジェクトで使いたい
ある程度アプリケーションが大きくなってくるとサブプロジェクトを作ってプロジェクト分割したくなる時があります。
例えばサブプロジェクトでplayのCacheAPIを利用したいと思っても残念ながらplayのCacheAPIはplay.api.Application
に依存しているため、直接使うことができません。
playアプリケーション起動時にplay.api.cache.Cache
の実装を渡してしまえばサブプロジェクトでもplayのCacheAPIを利用することができます。
インターフェースを定義します。
trait Cache { def get(key: String): Option[Any] def set(key : String, value : Any, expiration : Int): Unit def set(key: String, value: Any, expiration: scala.concurrent.duration.Duration): Unit def remove(key: String): Unit }
Cacheの実装を呼び出すクラスを定義します。
class CacheService { private var cache: Cache = null def setCacheImpl(src: Cache): Unit = { cache = src } def get(key: String): Option[Any] = { if (cache == null) { None } else { cache.get(key) } } def set(key: String, value: Any, expiration: Int): Unit = { cache.set(key, value, expiration) } def set(key: String, value: Any, expiration: Duration): Unit = { cache.set(key, value, expiration) } def remove(key: String): Unit = { cache.remove(key) } } object CacheService extends CacheService
GlobalオブジェクトのonStart()でアプリケーション起動時にCacheの実装を注入します。
object PlayCacheImpl extends Cache { override def get(key: String): Option[Any] = { play.api.cache.Cache.get(key) } override def set(key: String, value: Any, expiration: Int): Unit = { play.api.cache.Cache.set(key, value, expiration) } override def set(key: String, value: Any, expiration: Duration): Unit = { play.api.cache.Cache.set(key, value, expiration) } override def remove(key: String): Unit = { play.api.cache.Cache.remove(key) } } CacheService.setCacheImpl(PlayCacheImpl)
実際の使い方は以下のように呼び出せます。
val cacheMap = CacheService.get("キャッシュキー")
こうすることでPlay起動時に実装を注入し、サブプロジェクトでもPlayのCacheを使えるようになります。
他にもHTTPクライアントであるWS
やplay-mailer
など使いまわしたいけどplay.api.Application
に依存するAPIがいくつもあるので、無闇やたらに使うことは避けたほうがいいと思います。