Playframework2でCacheの実装をデフォルト(EhCache)から変更する方法のメモ。

Playframework2ではplay.cache.Cache*1クラスを利用することで、keyとvalueで保存するキャッシュ機能を利用することができます。
しかしこのクラスはキャッシュ機能のフロントエンドを提供しているだけで、キャッシュのバックエンド(実際の実装)は、デフォルトではEhCacheと呼ばれるライブラリが利用されているようです。
で、Playframework2では、このキャッシュのバックエンドを任意の実装に切り替えることが出来るので、例えばファイルシステムを用いたキャッシュだとかmemcacheだとかにキャッシュ実装を変更したいと言った場合でも、アプリケーションコードの変更なしに切り替えることができます。

やり方

キャッシュのフロントエンドは、プラグインに登録されているクラスのうちplay.api.cache.CachePluginを継承したクラスを利用するように作られていて、Playはデフォルトでplay.api.cache.EhCachePluginと言うplay.api.cache.CachePluginを継承したクラスを、起動時にプラグインとして設定します。
で、そのplay.api.cache.CachePluginは、play.api.cache.CacheAPIを返すapi()メソッドの実装を要求する、Pluginクラスを継承した抽象クラスです。
キャッシュのフロントエンドは最終的にはplay.api.cache.CacheAPIのAPIを利用しているため、play.api.cache.CachePluginを継承した任意のクラスを実装することで、キャッシュのバックエンドを切り替えることができる、という寸法です。

やってみた

という訳で、ダラダラ説明するより見たほうが早いので、java.util.Mapを利用した簡素なサンプルを作ってみました。

package plugins;

import java.util.HashMap;
import java.util.Map;

import play.Application;
import play.api.cache.CacheAPI;
import play.api.cache.CachePlugin;
import scala.Option;

public class OnMemoryCache extends CachePlugin {

	private final Map<String, String> repo;

	public OnMemoryCache(Application app){
		repo = new HashMap<String, String>();
	}

	@Override
	public boolean enabled() {
		return true;
	}

	@Override
	public void onStart(){
		System.out.println("onStart");
	}

	@Override
	public void onStop() {
		System.out.println("onStop");
	}

	@Override
	public CacheAPI api() {
		return new CacheAPI(){

			@Override
			public Option<Object> get(String key) {
				return Option.apply((Object)repo.get(key));
			}

			@Override
			public void remove(String key) {
				repo.remove(key);

			}

			@Override
			public void set(String key, Object value, int expireSeconds) {
				repo.put(key, (String)value);
			}
		};
	}
}

play.api.cache.CacheAPIは本当に最低限のAPIしか用意してないので、実装すること自体は簡単だと思います。


で、このクラスをplay.pluginsに追加してPlayのpluginとして登録するわけですが、ここで気をつけるべきなのはデフォルトで利用されるplay.api.cache.EhCachePluginの優先度です。
デフォルトのプラグインが登録されるよりも前に、この自作のプラグインを登録させないと意味がありません。
{play_root}/framework/src/play/src/main/resources/play.pluginsを見ると、どうやらplay.api.cache.EhCachePluginの優先度は600*2らしいので

550:plugins.OnMemoryCache

みたいな感じで、600よりも小さな任意の優先度で設定しましょう。
こうすることで、play.api.cache.EhCachePluginよりも先に自作キャッシュプラグインがPlayに設定されます。

*1:Scalaの場合はplay.api.cache.Cache

*2:バージョン2.1.1の場合