<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    捕風之巢

    統計

    留言簿(3)

    java友情鏈接

    閱讀排行榜

    評論排行榜

    Caching the result of methods using Spring and EHCache

    by:http://opensource.atlassian.com/confluence/spring/display/DISC/Caching+the+result+of+methods+using+Spring+and+EHCache

    Introduction

    Spring 1.1.1 introduced integration for EHCache for general cache use.

    I will show here a sample Interceptor that allows for declarative caching of methods results.

    Configure EHCache using Spring IoC

    Spring makes EHCache configuration very easy. All you need, is to provide a ehcache.xml file where you configure EHCache regions:

    <ehcache>

    ????
    <!--?Sets?the?path?to?the?directory?where?cache?.data?files?are?created.

    ?????????If?the?path?is?a?Java?System?Property?it?is?replaced?by
    ?????????its?value?in?the?running?VM.

    ?????????The?following?properties?are?translated:
    ?????????user.home?-?User's?home?directory
    ?????????user.dir?-?User's?current?working?directory
    ?????????java.io.tmpdir?-?Default?temp?file?path?
    -->
    ????
    <diskStore?path="java.io.tmpdir"/>


    ????
    <!--Default?Cache?configuration.?These?will?applied?to?caches?programmatically?created?through
    ????????the?CacheManager.

    ????????The?following?attributes?are?required?for?defaultCache:

    ????????maxInMemory???????-?Sets?the?maximum?number?of?objects?that?will?be?created?in?memory
    ????????eternal???????????-?Sets?whether?elements?are?eternal.?If?eternal,??timeouts?are?ignored?and?the?element
    ????????????????????????????is?never?expired.
    ????????timeToIdleSeconds?-?Sets?the?time?to?idle?for?an?element?before?it?expires.
    ????????????????????????????i.e.?The?maximum?amount?of?time?between?accesses?before?an?element?expires
    ????????????????????????????Is?only?used?if?the?element?is?not?eternal.
    ????????????????????????????Optional?attribute.?A?value?of?0?means?that?an?Element?can?idle?for?infinity
    ????????timeToLiveSeconds?-?Sets?the?time?to?live?for?an?element?before?it?expires.
    ????????????????????????????i.e.?The?maximum?time?between?creation?time?and?when?an?element?expires.
    ????????????????????????????Is?only?used?if?the?element?is?not?eternal.
    ????????overflowToDisk????-?Sets?whether?elements?can?overflow?to?disk?when?the?in-memory?cache
    ????????????????????????????has?reached?the?maxInMemory?limit.

    ????????
    -->

    ????
    <cache?name="org.taha.cache.METHOD_CACHE"
    ????????maxElementsInMemory
    ="300"
    ????????eternal
    ="false"
    ????????timeToIdleSeconds
    ="500"
    ????????timeToLiveSeconds
    ="500"
    ????????overflowToDisk
    ="true"
    ????????
    />
    </ehcache>

    Our Interceptor will use region "org.taha.cache.METHOD_CACHE" to cache methods results.
    Now we will use some Spring IoC to make this region accessible to our beans:

    <ehcache>

    ????
    <!--?Sets?the?path?to?the?directory?where?cache?.data?files?are?created.

    ?????????If?the?path?is?a?Java?System?Property?it?is?replaced?by
    ?????????its?value?in?the?running?VM.

    ?????????The?following?properties?are?translated:
    ?????????user.home?-?User's?home?directory
    ?????????user.dir?-?User's?current?working?directory
    ?????????java.io.tmpdir?-?Default?temp?file?path?
    -->
    ????
    <diskStore?path="java.io.tmpdir"/>


    ????
    <!--Default?Cache?configuration.?These?will?applied?to?caches?programmatically?created?through
    ????????the?CacheManager.

    ????????The?following?attributes?are?required?for?defaultCache:

    ????????maxInMemory???????-?Sets?the?maximum?number?of?objects?that?will?be?created?in?memory
    ????????eternal???????????-?Sets?whether?elements?are?eternal.?If?eternal,??timeouts?are?ignored?and?the?element
    ????????????????????????????is?never?expired.
    ????????timeToIdleSeconds?-?Sets?the?time?to?idle?for?an?element?before?it?expires.
    ????????????????????????????i.e.?The?maximum?amount?of?time?between?accesses?before?an?element?expires
    ????????????????????????????Is?only?used?if?the?element?is?not?eternal.
    ????????????????????????????Optional?attribute.?A?value?of?0?means?that?an?Element?can?idle?for?infinity
    ????????timeToLiveSeconds?-?Sets?the?time?to?live?for?an?element?before?it?expires.
    ????????????????????????????i.e.?The?maximum?time?between?creation?time?and?when?an?element?expires.
    ????????????????????????????Is?only?used?if?the?element?is?not?eternal.
    ????????overflowToDisk????-?Sets?whether?elements?can?overflow?to?disk?when?the?in-memory?cache
    ????????????????????????????has?reached?the?maxInMemory?limit.

    ????????
    -->

    ????
    <cache?name="org.taha.cache.METHOD_CACHE"
    ????????maxElementsInMemory
    ="300"
    ????????eternal
    ="false"
    ????????timeToIdleSeconds
    ="500"
    ????????timeToLiveSeconds
    ="500"
    ????????overflowToDisk
    ="true"
    ????????
    />
    </ehcache>

    Bean methodCache creates cache region org.taha.cache.METHOD_CACHE.

    Creating our MethodCacheInterceptor

    The interceptor implements org.aopalliance.intercept.MethodInterceptor. Whenever it kicks-in, it first checks if the intercepted method is configured to be cached. This allows to selectively configure bean methods for caching. If the method call is configured for caching, the interceptor builds the cache key for the method and checks if the method result is in the cache. If so, the cached result is returned, otherwise the intercepted method is called and the result cached for further use.

    org.taha.interceptor.MethodCacheInterceptor
    /*
    ?*?Copyright?2002-2004?the?original?author?or?authors.
    ?*
    ?*?Licensed?under?the?Apache?License,?Version?2.0?(the?"License");
    ?*?you?may?not?use?this?file?except?in?compliance?with?the?License.
    ?*?You?may?obtain?a?copy?of?the?License?at
    ?*
    ?*??????
    http://www.apache.org/licenses/LICENSE-2.0
    ?*
    ?*?Unless?required?by?applicable?law?or?agreed?to?in?writing,?software
    ?*?distributed?under?the?License?is?distributed?on?an?"AS?IS"?BASIS,
    ?*?WITHOUT?WARRANTIES?OR?CONDITIONS?OF?ANY?KIND,?either?express?or?implied.
    ?*?See?the?License?for?the?specific?language?governing?permissions?and
    ?*?limitations?under?the?License.
    ?
    */


    package?org.taha.interceptor;

    import?java.io.Serializable;

    import?org.aopalliance.intercept.MethodInterceptor;
    import?org.aopalliance.intercept.MethodInvocation;

    import?org.apache.commons.logging.LogFactory;
    import?org.apache.commons.logging.Log;

    import?org.springframework.beans.factory.InitializingBean;
    import?org.springframework.util.Assert;

    import?net.sf.ehcache.Cache;
    import?net.sf.ehcache.Element;

    /**
    ?*?
    @author?<a?href="mailto:irbouh@gmail.com">Omar?Irbouh</a>
    ?*?
    @since?2004.10.07
    ?
    */

    public?class?MethodCacheInterceptor?implements?MethodInterceptor,?InitializingBean?{
    ??privatestaticfinal?Log?logger?
    =?LogFactory.getLog(MethodCacheInterceptor.class);

    ??
    private?Cache?cache;

    ??
    /**
    ???*?sets?cache?name?to?be?used
    ???
    */

    ??
    public?void?setCache(Cache?cache)?{
    ????
    this.cache?=?cache;
    ??}


    ??
    /**
    ???*?Checks?if?required?attributes?are?provided.
    ???
    */

    ??
    public?void?afterPropertiesSet()?throws?Exception?{
    ????Assert.notNull(cache,?
    "A?cache?is?required.?Use?setCache(Cache)?to?provide?one.");
    ??}


    ??
    /**
    ???*?main?method
    ???*?caches?method?result?if?method?is?configured?for?caching
    ???*?method?results?must?be?serializable
    ???
    */

    ??publicObject?invoke(MethodInvocation?invocation)?
    throws?Throwable?{
    ????String?targetName??
    =?invocation.getThis().getClass().getName();
    ????String?methodName??
    =?invocation.getMethod().getName();
    ????Object[]?arguments?
    =?invocation.getArguments();
    ????Object?result;

    ????logger.debug(
    "looking?for?method?result?in?cache");
    ????String?cacheKey?
    =?getCacheKey(targetName,?methodName,?arguments);
    ????Element?element?
    =?cache.get(cacheKey);
    ????
    if?(element?==?null)?{
    ??????
    //call?target/sub-interceptor
    ??????logger.debug("calling?intercepted?method");
    ??????result?
    =?invocation.proceed();

    ??????
    //cache?method?result
    ??????logger.debug("caching?result");
    ??????element?
    =?new?Element(cacheKey,?(Serializable)?result);
    ??????cache.put(element);
    ????}

    ????
    return?element.getValue();
    ??}


    ??
    /**
    ???*?creates?cache?key:?targetName.methodName.argument0.argument1
    ???
    */

    ??privateString?getCacheKey(String?targetName,
    ?????????????????????????????String?methodName,
    ?????????????????????????????Object[]?arguments)?
    {
    ????StringBuffer?sb?
    =?newStringBuffer();
    ????sb.append(targetName)
    ??????.append(
    ".").append(methodName);
    ????
    if?((arguments?!=?null)?&&?(arguments.length?!=?0))?{
    ??????
    for?(int?i=0;?i<arguments.length;?i++)?{
    ????????sb.append(
    ".")
    ??????????.append(arguments[i]);
    ??????}

    ????}


    ????
    return?sb.toString();
    ??}

    }
    MethodCacheInterceptor source shows that:
    • by default, all methods result are cached (methodNames is null)
    • cache region is configured using IoC
    • cacheKey takes in consideration method arguments

    Using MethodCacheInterceptor

    The following excerpt shows how to configure MethodCacheInterceptor:

    <bean?id="methodCacheInterceptor"?class="org.taha.interceptor.MethodCacheInterceptor">
    ??
    <property?name="cache">
    ????
    <ref?local="methodCache"?/>
    ??
    </property>
    </bean>

    <bean?id="methodCachePointCut"?class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    ??
    <property?name="advice">
    ????
    <ref?local="methodCacheInterceptor"/>
    ??
    </property>
    ??
    <property?name="patterns">
    ????
    <list>
    ??????
    <value>.*methodOne</value>
    ??????
    <value>.*methodTwo</value>
    ????
    </list>
    ??
    </property>
    </bean>

    <bean?id="myBean"?class="org.springframework.aop.framework.ProxyFactoryBean">
    ??
    <property?name="target">
    ???
    <bean?class="org.taha.beans.MyBean"/>
    ??
    </property>
    ??
    <property?name="interceptorNames">
    ????
    <list>
    ??????
    <value>methodCachePointCut</value>
    ????
    </list>
    ??
    </property>
    </bean>
    Further improvements:

    It will be very helpfull to add the following to MethodCacheInterceptor:

    • refactor the code so that the interceptor no longer depends on EHCache
    • add arguments to methods configuration:
      <property?name="methodNames">
      ??
      <list>
      ????
      <value>methodOne(java.lang.String,?int)</value>
      ????
      <value>methodOne(java.lang.String,?java.lang.String)</value>
      ??
      </list>
      </property>
    • add regular expressions to method configuration
      <property?name="methodNames">
      ??
      <list>
      ????
      <value>add*</value>
      ??
      </list>
      </property>

    Changes:

    • MethodCacheInterceptor now implements InitializingBean
    • removed property methodNames and setter setMethodNames(java.lang.String)
    • MethodCacheInterceptor can be configured using regular PointCutAdvisor
    • using org.springframework.util.Assert to eagerly check if property cache is not null

    posted on 2006-10-11 11:27 捕風 閱讀(399) 評論(0)  編輯  收藏 所屬分類: java高級

    主站蜘蛛池模板: 亚洲精品无码久久久久秋霞| 国产A在亚洲线播放| 精品免费久久久久久久| 国产成人精品日本亚洲专区61| 亚洲尹人香蕉网在线视颅| 国产真人无码作爱免费视频| 亚洲线精品一区二区三区影音先锋 | 巨胸喷奶水www永久免费| 亚洲美女在线国产| 亚洲精品动漫在线| 日本免费人成在线网站| 亚洲国产成人超福利久久精品| 蜜桃AV无码免费看永久| 亚洲人成电影青青在线播放| 免费看无码自慰一区二区| 日韩国产精品亚洲а∨天堂免| 成人国产mv免费视频| 亚洲精品在线观看视频| 9420免费高清在线视频| 亚洲AV无码成人专区| 免费看AV毛片一区二区三区| 永久免费无码日韩视频| 欧美日韩国产免费一区二区三区| 亚洲AV日韩AV天堂久久| 6080午夜一级毛片免费看 | 成在人线AV无码免费| 亚洲AV无码专区国产乱码4SE| 在线涩涩免费观看国产精品| 亚洲一区二区女搞男| 足恋玩丝袜脚视频免费网站| 亚洲色成人WWW永久在线观看| 中文毛片无遮挡高清免费| 久久亚洲精品人成综合网| 在线播放高清国语自产拍免费| 91亚洲精品第一综合不卡播放| 你是我的城池营垒免费看| 亚洲精品成人网站在线播放| 日本免费一区尤物| 全免费a级毛片免费看| 国产亚洲无线码一区二区| 大学生一级毛片免费看|