http://www.playframework-ja.org/documentation/1.2.7/cache
パフォーマンスの高いシステムを作成するため、データのキャッシュが必要になる場合があります。Play にはキャッシュライブラリがあり、分散環境下では Memcahed を使用します。
Memcached を設定しない場合、Play は JVM ヒープにデータを保存するスタンドアロンキャッシュを使用します。
public static void allProducts() {
// キャッシュ取得
List<Product> products = Cache.get("products", List.class);
if(products == null) {
products = Product.findAll();
// キャッシュ登録
Cache.set("products", products, "30mn");
}
render(products);
}
Ehcache を利用
EhcacheはオープンソースのJavaEEや軽量コンテナ等で広く使われているキャッシュ機構である。メモリとディスクストレージ、レプリケーション、リスナ、キャッシュローダー、キャッシュ拡張、キャッシュ例外ハンドラ、gzipキャッシュサーブレットフィルタ、RESTとSOAPのAPIといった機能を持つ。EhcacheはApache Licenseで利用できる。
Ehcacheは2003年にGreg Luckにより開発された。2009年、プロジェクトはTerracotta, Inc.により買収された。ソフトウェア自体は、引き続きオープンソースとされている。(Wikipedia)
public abstract class Cache {
// キャッシュ実装クラスのインスタンス保持
public static CacheImpl cacheImpl;
// 初期化
public static void init() {
// キャッシュ実装にmemcachedを利用する場合
if (Play.configuration.getProperty("memcached", "disabled").equals("enabled")) {
try {
cacheImpl = MemcachedImpl.getInstance(true);
Logger.info("Connected to memcached");
} catch (Exception e) {
Logger.error(e, "Error while connecting to memcached");
Logger.warn("Fallback to local cache");
cacheImpl = EhCacheImpl.getInstance();
}
// デフォルトキャッシュ機構を利用する場合
} else {
cacheImpl = EhCacheImpl.newInstance();
}
}
public class EhCacheImpl implements CacheImpl {
// シングルトンインスタンス保持
private static EhCacheImpl uniqueInstance;
// Ehcacheインスタンス保持
CacheManager cacheManager;
net.sf.ehcache.Cache cache;
private static final String cacheName = "play";
// コンストラクタ
private EhCacheImpl() {
this.cacheManager = CacheManager.create();
this.cacheManager.addCache(cacheName);
this.cache = cacheManager.getCache(cacheName);
}
// インスタンスを生成して取得
public static EhCacheImpl newInstance() {
uniqueInstance = new EhCacheImpl();
return uniqueInstance;
}
// キャッシュ登録
public void add(String key, Object value, int expiration) {
if (cache.get(key) != null) {
return;
}
Element element = new Element(key, value);
element.setTimeToLive(expiration);
cache.put(element);
}
// キャッシュ取得
public Object get(String key) {
Element e = cache.get(key);
return (e == null) ? null : e.getValue();
}
http://www.playframework-ja.org/documentation/1.1.1/releasenotes-1.1#anamecachea
アクションとテンプレートにより簡単にキャッシュを統合することができる 2 つの新機能を用意しました。最初に、 @play.cache.CacheFor アノテーションを追加することで、アクションの結果を容易にキャッシュすることができるようになりました。これは見せかけの静的ページを作るのにとても便利です。
@CacheFor("1h")
public static void index() {
render();
}
// Example: @CacheFor("1h")
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CacheFor {
String value() default "1h";
String id() default "";
}
public static void invoke(Http.Request request, Http.Response response) {
try {
// @Before処理
handleBefores(request);
// メソッド処理
Result actionResult = null;
String cacheKey = null;
// キャッシュ設定確認(GET/HEADメソッド時のみ)
if ((request.method.equals("GET") || request.method.equals("HEAD"))
// @CacheForアノテーションが設定されていれば
&& actionMethod.isAnnotationPresent(CacheFor.class)) {
cacheKey = actionMethod.getAnnotation(CacheFor.class).id();
if ("".equals(cacheKey)) {
// Getクエリストリングをキャッシュキーにする
cacheKey = "urlcache:" + request.url + request.querystring;
}
// キャッシュ取得
actionResult = (Result) play.cache.Cache.get(cacheKey);
}
// キャッシュ登録なければ
if (actionResult == null) {
ControllerInstrumentation.initActionCall();
try {
//メソッド実行
inferResult(invokeControllerMethod(actionMethod));
} catch(Result result) {
actionResult = result;
// キャッシュ設定があれば、キャッシュする
if (cacheKey != null) {
play.cache.Cache.set(cacheKey, actionResult, actionMethod.getAnnotation(CacheFor.class).value());
}
ehcache.xmlにて設定
メモリに格納する最大エントリ数(Playデフォルト10000件)
タイムアウト値は無視して保持するかどうか(Playデフォルトfalse)
キャッシュのアイドル秒数(Playデフォルト120秒)
キャッシュの有効秒数(Playデフォルト120秒)
メモリへの格納数をこえた場合にディスクに格納するかどうか(Playデフォルトfalse)
ディスクに格納する最大エントリ数(Playデフォルト10000000件)
再起動する際にディスクキャッシュを永続化するかどうか(Playデフォルトfalse)
ディスクキャッシュの期限をチェック間隔秒(Playデフォルト120秒)
メモリに格納するエントリが最大値に達したときの振る舞いをLRU(最も古く使われたもの)、FIFO(最も古く登録したもの)、LFU(最も使われていないもの)のいずれかで指定(PlayデフォルトLFU)