intra-mart Accel Platform アクセスコンテキスト 拡張プログラミングガイド 第2版 2015-12-01

3.2. アクセスコンテキストのキャッシュ機能の実装例

この章では、アクセスコンテキストをキャッシュする方法を説明します。
前章「アクセスコンテキストの実装例 」で作成したアクセスコンテキストはキャッシュされていないため、ライフサイクルが開始されるたびに都度コンテキストビルダによってインスタンスが作成されます。
ここでは、アクセスコンテキストをキャッシュして、毎回インスタンスを作成しないようにします。
キャッシュについての詳細は、「 アクセスコンテキスト仕様書 」-「 キャッシュ 」を参照してください。

3.2.1. 機能定義と作業の流れ

この章で作成するアクセスコンテキストのキャッシュ処理の要件は、以下の通りです。
  • 一度アクセスコンテキストのインスタンスを生成した場合は、キャッシュする。
  • 次回アカウントコンテキストを要求されたときは、キャッシュから返却する。
アクセスコンテキストをキャッシュするための作業手順は、以下の通りです。
順序 作業内容 解説
1 キャッシュに対応するコンテキストビルダクラスを実装する。 キャッシュに対応するコンテキストビルダの作成
2 アクセスコンテキスト設定を追加する。 アクセスコンテキスト設定の追加
3 アクセスコンテキストの動作を確認する。 アクセスコンテキストの動作確認

3.2.2. キャッシュに対応するコンテキストビルダの作成

キャッシュに対応するコンテキストビルダクラスを作成します。
クラスを作成する場合は、以下のクラスを継承してください。
jp.co.intra_mart.system.context.core.cache.CachingContextBuilderSupport
CachingContextBuilderSupport クラスを継承することで、create メソッドの実装が必須となります。
実装方法とメソッドの詳細は、前章の「コンテキストビルダの作成 」と同様です。
前章で作成したコンテキストビルダを流用する場合は、継承しているクラスを ContextBuilderSupport から CachingContextBuilderSupport に変更してください。
完全修飾子(FQCN) sample.CachingSimpleUserContextBuilder

package sample;

import java.util.Date;
import java.util.Locale;

import jp.co.intra_mart.common.platform.log.Logger;
import jp.co.intra_mart.foundation.context.Contexts;
import jp.co.intra_mart.foundation.context.core.Resource;
import jp.co.intra_mart.foundation.context.model.AccountContext;
import jp.co.intra_mart.foundation.context.model.Context;
import jp.co.intra_mart.foundation.exception.BizApiException;
import jp.co.intra_mart.foundation.i18n.datetime.DateTime;
import jp.co.intra_mart.foundation.i18n.timezone.SystemTimeZone;
import jp.co.intra_mart.foundation.master.user.UserManager;
import jp.co.intra_mart.foundation.master.user.model.User;
import jp.co.intra_mart.foundation.master.user.model.UserBizKey;
import jp.co.intra_mart.system.context.core.cache.CachingContextBuilderSupport;

public class CachingSimpleUserContextBuilder extends CachingContextBuilderSupport {

    private static final Logger LOGGER = Logger.getLogger(CachingSimpleUserContextBuilder.class);

    /**
     * アクセスコンテキストのインスタンスを生成します。
     * @param resource 環境情報
     * @return アクセスコンテキストのインスタンス
     */
    @Override
    protected Context create(final Resource resource) {
        try {
            // ここに到達したことをログに出力
            LOGGER.info("SimpleUserContext created.");

            // アクセスコンテキストのインスタンスを生成して返却
            return createNewContext();
        } catch (final BizApiException e) {
            throw new RuntimeException(e);
        }
    }

    private SimpleUserContext createNewContext() throws BizApiException {
        // ログインユーザの情報をアカウントコンテキストから取得
        final AccountContext accountContext = Contexts.get(AccountContext.class);
        final String userCd = accountContext.getUserCd();
        final Locale locale = accountContext.getLocale();

        // ログインユーザの情報 (ユーザコード、ロケール) をキーとしてユーザ情報を取得
        final User user = getUser(userCd, locale);
        if (user == null) {
            // ユーザ情報が取得できないときは、空のアクセスコンテキストのインスタンスを返却
            return new SimpleUserContext();
        }

        // アクセスコンテキストのインスタンスに、ユーザ情報を設定
        final SimpleUserContext context = new SimpleUserContext();
        context.setUserName(user.getUserName());
        context.setMailAddress(user.getEmailAddress1());

        // アクセスコンテキストのインスタンスを返却
        return context;
    }

    private Date getBaseTime() {
        // ログインユーザのタイムゾーンで現在日付を取得
        final DateTime userDate = new DateTime(Contexts.get(AccountContext.class).getTimeZone());
        return new DateTime(SystemTimeZone.getDefaultTimeZone(), userDate.getYear(), userDate.getMonthOfYear(), userDate.getDayOfMonth()).getDate();
    }

    private User getUser(final String userCd, final Locale locale) throws BizApiException {
        // IM共通マスタの検索条件を設定
        final UserManager manager = new UserManager();
        final UserBizKey bizKey = new UserBizKey();
        bizKey.setUserCd(userCd);

        // IM共通マスタからユーザ情報を検索
        final User user = manager.getUser(bizKey, getBaseTime(), locale, false);
        return user;
    }

}

3.2.3. アクセスコンテキスト設定の追加

アクセスコンテキストと、キャッシュに対応したコンテキストビルダを紐付ける設定を、「アクセスコンテキスト設定」に追加します。
設定ファイルに、以下のような形式で記述してください。
前章の「アクセスコンテキストの設定 」で作成した設定ファイルに、キャッシュに関する設定を追加します。
パス WEB-INF/conf/context-config/{任意のファイル名}.xml

<?xml version="1.0"?>
<context-config
    xmlns="http://intra-mart.co.jp/foundation/context/context-config"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://intra-mart.co.jp/foundation/context/context-config ../../schema/context-config.xsd">

  <context
      name="sample.SimpleUserContext"
      depends="jp.co.intra_mart.foundation.context.model.AccountContext">

    <builder target="platform.request">
      <builder-class>sample.CachingSimpleUserContextBuilder</builder-class>
      <init-param>
        <param-key>cache-policy</param-key>
        <param-value>session-user-daily</param-value>
      </init-param>
    </builder>

  </context>

</context-config>
設定が必要なタグとその説明は、以下の通りです。
  • init-param タグ内の cache-policy 設定

    キャッシュのポリシーを指定してください。
    今回の例では、 session-user-daily を指定します。
    キャッシュに関する設定の詳細は、「 アクセスコンテキスト仕様書 」-「 キャッシュ設定 」を参照してください。

3.2.4. アクセスコンテキストの動作確認

作成したアクセスコンテキストのキャッシュが動作しているか、以下の手順で確認します。
  1. サーバ起動時のログを確認します。

    アクセスコンテキスト、コンテキストビルダ、および、設定ファイルが正しくアプリケーションサーバに配置されている場合、サーバ起動時に以下のシステムログが出力されます。
    [I.IWP.CONTEXT.MANAGER.10001] Used context. sample.SimpleUserContext
    
    実際の出力例
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcs9     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.context.model.ClientContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcsa     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.context.model.AccountContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcsb     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.job_scheduler.JobSchedulerContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcsc     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.user_context.model.UserContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcsd     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.authz.context.AuthzSubjectContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcse     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. sample.SimpleUserContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.service.impl.ServiceControllerImpl     5ib6n4szdi8sf     -  [I.IWP.SERVICE.00009]   Initialize service "server.service.queue.management".
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.service.impl.ServiceControllerImpl     5ib6n4szdi8sg     -  [I.IWP.SERVICE.00009]   Initialize service "server.service.task.management".
    
  2. ログイン時に、ログ、および、アクセスコンテキストの保持内容を確認します。

    任意のユーザ(例:サンプルユーザの青柳)でログイン後、CachingSimpleUserContextBuilder#create() メソッドの冒頭で実装しているログが以下のように出力されますので、システムログを確認してください。
    ログが出力されていれば、アクセスコンテキストの作成処理が正常に行われています。
    [] SimpleUserContext created.
    
    実際の出力例
    [2014-05-01 12:00:00.000]  [resin-port-8080-11] INFO  sample.CachingSimpleUserContextBuilder    5ib6n4umb3mos     -  [] SimpleUserContext created.
    
    アクセスコンテキストの保持内容を確認するため、以下の URL にアクセスしてください。

    http://<HOST>:<PORT>/<CONTEXT_PATH>/sample/context/context_view.jsp

    「Context: sample.SimpleUserContext」カテゴリが表示され、各プロパティに想定通りの値が表示されていることを確認します。
    また、キャッシュが働いているため、「Cached Context」列に同じ内容が表示されます。(下図の緑枠)
    ../../_images/make_context_2.png
    図 アクセスコンテキストの内容
  3. 「個人設定」を変更して、アクセスコンテキストの保持内容が変更されていないことを確認します。

    「個人設定」の「ロケール」を変更後にページを再表示すると、アクセスコンテキストの保持内容が変更されないことが確認できます。
    これはキャッシュが正常に動作しているためです。
    キャッシュが動作しているため、「個人設定」の「ロケール」を変更しても、以下のログは再度出力されません。
    [] SimpleUserContext created.
    
    「ロケール」を変更後、アクセスコンテキストの内容を変更するためには、次章で説明するアクセスコンテキストの切替処理が必要です。