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

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

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

    于吉吉的技術(shù)博客

    建造高性能門戶網(wǎng)

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      65 隨筆 :: 6 文章 :: 149 評(píng)論 :: 0 Trackbacks
    由于系統(tǒng)需求需 要對(duì)各個(gè)接口進(jìn)行key-value緩存(以參數(shù)為key,返回的對(duì)象為value),當(dāng)然對(duì)于這種情況首先考慮到的是使用aop,前段時(shí)間看過 aspectj的一些介紹,借此機(jī)會(huì)正好加以應(yīng)用和體會(huì)一下,aspectj是AOP最早成熟的java實(shí)現(xiàn),它稍微擴(kuò)展了一下java語(yǔ)言,增加了一些 keyword等,具體的aspectj的基本語(yǔ)法見[ur=http://today.java.net/pub/a/today/2003/12 /26/ch3AspectJSyntaxBasics.html]這里[/url],進(jìn)行緩存的框架使用較成熟的ehcache.
    下面開始進(jìn)行配置
    首先是ehcache的配置文件

    <?xml version="1.0" encoding="UTF-8"?>  
    <ehcache>  
         
    <diskStore path="/home/workspace/gzshine/trunk/ehcache"/>  
         
    <cache name="DEFAULT_CACHE"  
             maxElementsInMemory
    ="10000"  
             eternal
    ="false"  
             timeToIdleSeconds
    ="3600"  
             timeToLiveSeconds
    ="3600"  
             overflowToDisk
    ="true"/>  
    </ehcache> 

    這個(gè)的DEFAULT_CACHE是默認(rèn)配置,最大的緩存數(shù)為10000,時(shí)間為一個(gè)小時(shí)

    接下來(lái)的是spring下的配置

    <?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans"  
         xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance"  
         xmlns:aop
    ="http://www.springframework.org/schema/aop"  
         xmlns:tx
    ="http://www.springframework.org/schema/tx"  
         xmlns:context
    ="http://www.springframework.org/schema/context"  
         xsi:schemaLocation
    ="  
            http://www.springframework.org/schema/beans  
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
            http://www.springframework.org/schema/tx  
            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd  
            http://www.springframework.org/schema/aop  
            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
            http://www.springframework.org/schema/context  
            http://www.springframework.org/schema/context/spring-context-2.5.xsd"
    >  
       
    <!-- ##############  aspectj 4 ehcache   ############# -->  
           
         
    <aop:aspectj-autoproxy proxy-target-class="true"/>  
         
    <bean id = "methodCacheAspectJ" class="com.***.shine.aspectj.MethodCacheAspectJ" >  
             
    <property name="cache">  
                 
    <ref local="methodCache" />  
             
    </property>  
         
    </bean>  
           
         
    <bean id="cacheManager"  
             class
    ="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">  
             
    <property name="configLocation">  
                 
    <value>classpath:ehcache.xml</value>  
             
    </property>  
         
    </bean>  
           
         
    <!-- 定義ehCache的工廠,并設(shè)置所使用的Cache name -->  
           
         
    <bean id="methodCache"  
             class
    ="org.springframework.cache.ehcache.EhCacheFactoryBean">  
             
    <property name="cacheManager">  
                 
    <ref local="cacheManager" />  
             
    </property>  
             
    <property name="cacheName">  
                 
    <value>DEFAULT_CACHE</value>  
             
    </property>  
         
    </bean> 

    <aop:aspectj-autoproxy proxy-target-class="true"/>
    是為aspectj在所有class下開啟自動(dòng)動(dòng)態(tài)代理
    <bean id="cacheManager">指定剛剛的ehcache配置文件


    接下來(lái)編寫一個(gè)自定義的annotation

     package com.***.shine.cache;  
       
     
    import java.lang.annotation.Documented;  
     
    import java.lang.annotation.ElementType;  
     
    import java.lang.annotation.Retention;  
     
    import java.lang.annotation.RetentionPolicy;  
     
    import java.lang.annotation.Target;  
       
     @Target({ElementType.METHOD,ElementType.TYPE})  
     @Retention(RetentionPolicy.RUNTIME)  
     @Documented  
     
    public @interface MethodCache {  
         
    int second() default 0;   
     } 

    <bean id = "methodCacheAspectJ">是一個(gè)aspectj進(jìn)行Pointcuts和Advice的類需注入methodCache

     package com.***.shine.aspectj;  
       
     @Aspect  
     
    public class MethodCacheAspectJ {  
         Log logger 
    = LogFactory.getLog(MethodCacheAspectJ.class);  
           
         
    private Cache cache;  
           
         
    /** 
          * 設(shè)置緩存名 
          
    */  
         
    public void setCache(Cache cache) {  
             
    this.cache = cache;  
         }   
           
         @Pointcut(
    "@annotation(com.***.shine.cache.MethodCache)")  
         
    public void methodCachePointcut(){    
         }  
           
         @Around(
    "methodCachePointcut()")  
         
    public Object methodCacheHold(ProceedingJoinPoint joinPoint) throws Throwable{  
             String targetName 
    = joinPoint.getTarget().getClass().getName();  
             String methodName 
    = joinPoint.getSignature().getName();  
             Object[] arguments 
    = joinPoint.getArgs();  
             Object result 
    = null;  
             String cacheKey 
    = getCacheKey(targetName, methodName, arguments);  
             Element element 
    = cache.get(cacheKey);  
             
    if (element == null) {  
                 
    try{  
                     result 
    = joinPoint.proceed();  
                 }
    catch(Exception e){  
                     logger.info(e);  
                 }  
                 
    if(result!=null){  
                     
    try{  
                         element 
    = new Element(cacheKey, (Serializable) result);  
                         Class targetClass 
    = Class.forName(targetName);  
                         Method[] method 
    = targetClass.getMethods();  
                         
    int second = 0;  
                         
    for(Method m:method){  
                             
    if (m.getName().equals(methodName)) {  
                                 Class[] tmpCs 
    = m.getParameterTypes();  
                                 
    if(tmpCs.length==arguments.length){  
                                     MethodCache methodCache 
    = m.getAnnotation(MethodCache.class);  
                                     second 
    = methodCache.second();  
                                     
    break;  
                                 }  
                             }  
                         }  
                         
    if(second>0){ // annotation沒有設(shè)second值則使用ehcache.xml中自定義值  
                             element.setTimeToIdle(second);  
                             element.setTimeToLive(second);  
                         }  
                         cache.put(element);  
                     }
    catch(Exception e){  
                         logger.info(
    "!!!!!!!!!"+cacheKey+"!!!!!!!!!未能執(zhí)行方法緩存"+e);  
                     }  
                 }  
             }  
             
    return element.getValue();  
         }  
       
          
    private String getCacheKey(String targetName, String methodName,  
                 Object[] arguments) {  
             StringBuffer sb 
    = new StringBuffer();  
             sb.append(targetName).append(
    ".").append(methodName);  
             
    if ((arguments != null&& (arguments.length != 0)) {  
                 
    for (int i = 0; i < arguments.length; i++) {  
                     
    if (arguments[i] instanceof Date) {  
                         sb.append(
    ".").append(  
                                 DateUtil.datetoString((Date) arguments[i]));  
                     } 
    else {  
                         sb.append(
    ".").append(arguments[i]);  
                     }  
                 }  
             }  
             
    return sb.toString();  
         }  
     } 


    @Pointcut("@annotation(com.netease.shine.cache.MethodCache)")
    對(duì)有應(yīng)用com.netease.shine.cache.MethodCache進(jìn)行注解的方法進(jìn)行橫切面攔截
    @Around("methodCachePointcut()")
    并在Advice中處理這個(gè)Pointcut,這里的的Advice使用的是Around(環(huán)繞通知)
    String cacheKey = getCacheKey(targetName, methodName, arguments);
    接下來(lái)使用類型,方法名,參數(shù)為key進(jìn)入緩存處理
    Element element = cache.get(cacheKey);
    當(dāng)然如果在cache隊(duì)列中取得非null對(duì)象則直接返回該對(duì)象
    MethodCache methodCache = m.getAnnotation(MethodCache.class);
    second = methodCache.second();
    取得second的值(緩存的時(shí)間,如在@annotation中無(wú)重寫只為int second() default 0)
    element.setTimeToIdle(second);
    element.setTimeToLive(second);
    如果非零則重新設(shè)置緩存時(shí)間

    @MethodCache(second=300)  
    public List<Sort> getSort(int type,int parentid){  
         System.out.println(
    "!!!!!!!!!!!!!沒緩存到");  
         Row row 
    = new Row();  
         row.put(
    "type", type);  
         row.put(
    "parentid", parentid);  
         
    return (List<Sort>)gz_Template.queryForList("sort.getSort", row);  
     } 


    ----------------------------------------

    陳于喆
    Mail: chenyz@corp.netease.com

    posted on 2010-08-23 10:35 陳于喆 閱讀(8528) 評(píng)論(0)  編輯  收藏 所屬分類: spring

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 免费无码又爽又刺激高潮的视频| 亚洲日本va在线观看| 成人人免费夜夜视频观看| 国产精品99久久免费观看| 污网站在线观看免费| 亚洲无码一区二区三区| 亚洲最新在线视频| 亚洲精品天天影视综合网| 亚洲午夜久久久久久久久电影网| 国产在线ts人妖免费视频| 在线a人片天堂免费观看高清| 四虎在线成人免费网站| 久久国产精品一区免费下载| WWW国产成人免费观看视频| WWW亚洲色大成网络.COM| 亚洲专区一路线二| 亚洲区视频在线观看| 亚洲欧洲精品在线| 亚洲国产成人va在线观看网址| 91亚洲一区二区在线观看不卡| 亚洲AV无码国产丝袜在线观看| 亚洲日韩欧洲乱码AV夜夜摸| 亚洲中文字幕在线第六区| 亚洲六月丁香婷婷综合| 91嫩草私人成人亚洲影院| 久久久久亚洲av无码专区喷水| 亚洲国产精彩中文乱码AV| 亚洲阿v天堂在线| 亚洲AV日韩AV鸥美在线观看| 亚洲av综合av一区| 久久久亚洲精品无码| 亚洲s色大片在线观看| 亚洲αv久久久噜噜噜噜噜| 久久精品夜色国产亚洲av| 亚洲尹人香蕉网在线视颅| 亚洲春色另类小说| 亚洲乱码在线观看| 国产亚洲一卡2卡3卡4卡新区| 免费国产黄网站在线看| 精品国产免费人成网站| 久久精品一区二区免费看|