EhCache缓存介绍

Ehcache使用简单介绍:http://blog.csdn.net/wp1603710463/article/details/50198229

ehcache与spring注解实例:http://blog.csdn.net/u010955843/article/details/51692311

EhCache介绍:http://chenjumin.iteye.com/blog/684926

Spring 整合Ehcache http://m.blog.csdn.net/baidu_22796075/article/details/72677325

ehcache-setting.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <!-- 指定一个文件目录,当EhCache把数据写到硬盘上时,将把数据写到这个文件目录下 -->
    <diskStore path="java.io.tmpdir"/>

    <!-- 设定缓存的默认数据过期策略 -->
    <!--timeToIdleSeconds 当缓存闲置n秒后销毁 --> 
    <!--timeToLiveSeconds 当缓存存活n秒后销毁 --> 
    <!-- 
    缓存配置 
           name:缓存名称。 
           maxElementsInMemory:缓存最大个数。 
           eternal:对象是否永久有效,一但设置了,timeout将不起作用。 
           timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 
           timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 
           overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。 
           diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 
           maxElementsOnDisk:硬盘最大缓存个数。 
           diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. 
           diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 
           memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 
           clearOnFlush:内存数量最大时是否清除。 
    -->
    <defaultCache
            maxElementsInMemory="10000" 
            eternal="false" 
            overflowToDisk="true"
            timeToIdleSeconds="10"
            timeToLiveSeconds="20"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"/>

    <cache name="cacheWeather" 
        maxElementsInMemory="100000"
        eternal="false"
        overflowToDisk="true"
        timeToIdleSeconds="300"
        timeToLiveSeconds="3600"
        memoryStoreEvictionPolicy="LRU"/>

</ehcache>

applicationContext.xml

    <!-- EhCache  start -->
    <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
    <cache:annotation-driven cache-manager="cacheManager"/>

    <!-- 声明cacheManager -->
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">  
        <property name="cacheManager" ref="ehcache"></property>  
    </bean> 

    <!-- cacheManager工厂类,指定ehcache.xml的位置 -->
    <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">  
        <property name="configLocation" value="classpath:ehcache-setting.xml"></property>  
    </bean>  
    <!-- EnCache  end -->

使用标签:

    /**
     * value:缓存位置名称,不能为空,如果使用EHCache,就是ehcache.xml中声明的cache的name
     *  key:缓存的key,默认为空,既表示使用方法的参数类型及参数值作为key,支持SpEL
     *  condition:触发条件,只有满足条件的情况才会加入缓存,默认为空,既表示全部都加入缓存,支持SpEL
     */
    //将缓存保存进andCache,并使用参数中的userId加上一个字符串(这里使用方法名称)作为缓存的key     
    @Cacheable(value="cacheWeather",key="#lat.substring(0,5)+#lon.substring(0,6)") 
    public List<ResponseDataItemPojo> getCurrentWeather(String lat, String lon,
            String language) throws JsonParseException, JsonMappingException,
    @Cacheable(value="cacheTest",key="#param")
    public String getTimestamp(String param) {
        Long timestamp = System.currentTimeMillis();
        return timestamp.toString();
    }

    //将缓存保存进andCache,并使用参数中的userId加上一个字符串(这里使用方法名称)作为缓存的key     
    @Cacheable(value="cacheTest",key="#userId + 'findById'")    
    public UserTest findById(Long userId) {    
        UserTest user = userTestDao.queryUserByid(userId); 
        System.out.println("数据库查询..........");
        return user ;           
    }    
    //将缓存保存进andCache,并当参数userId的长度小于8时才保存进缓存,默认使用参数值及类型作为缓存的key    
    @Cacheable(value="andCache",condition="#userId.length()< 8")    
    public boolean isReserved(String userId) {    
        System.out.println("hello andCache "+userId);
        userTestDao.queryUserByid(Long.getLong(userId));
        return false;    
    }

    //  @Cacheable({"cache1", "cache2"})//Cache是发生在cache1和cache2上的
    @Cacheable(value="cacheTest",key="#id")
    public UserTest queryById(Long id) {
        System.out.println("数据库查询..........");
        return userTestDao.queryUserByid(id);
    }

    //@Cacheable(value="users", key="#p0")  使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”
    @Cacheable(value="cacheTest",key="#p0")
    public UserTest queryById(Long id,String name) {
        System.out.println("数据库查询..........");
        return userTestDao.queryUserByid(id);
    }

    @Cacheable(value="cacheTest",key="#root.methodName")
    public List<UserTest> queryList(){
        return userTestDao.queryList();
    }
    //当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性
    @Cacheable(value="cacheTest",key="methodName")
    public UserTest queryById(){
        return userTestDao.queryUserByid(12l);
    }


    /**
     * key的名称一样然后类型一样就会干扰缓存结果
     */
    //测试缓存干扰
    //测试缓存key一样时的状况
    @Cacheable(value="cacheTest",key="#id")
    public List<UserTest> queryList(Long id){
        return userTestDao.queryList();
    }

EhCacheManager

不用标签时的工具类:

package com.gongren.ehCache;

import java.io.Serializable;
import java.net.URL;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

import com.gongren.daoCache.QueryMsgTestDao;
import com.gongren.entity.MyCacheObject;
import com.gongren.entity.UserTest;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.Status;

public class EhCacheManager {
    private static Logger logger = Logger.getLogger(EhCacheManager.class);
    /** 
     * Ehanche的缓存管理 
     */  
    private static CacheManager cacheManager = null;    
    private static String configPath="ehcache-setting.xml";//配置文件
    private QueryMsgTestDao queryMsgTestDao;//查询

    //缓存定义  
    public static String CACHE_MYCOMMONCACHE="cacheTest";//定义文件中配置的缓存  
    //缓存中的Element定义  
    public static String ELEMENT_MYCOMMONCACHE_DICTIONARY="dictionaryList";//缓存元素   

    //实例化cacheManager,单例模式  
    public static CacheManager getCacheManagerInstance(){
        if(cacheManager==null){
            synchronized(EhCacheManager.class){//线程安全
                URL configUrl=null;
                configUrl = EhCacheManager.class.getClassLoader().getResource(configPath);
                cacheManager = CacheManager.create(configUrl); 
            }
        }
        return cacheManager; 
    }

    public static CacheManager getCacheManager() {  
        return getCacheManagerInstance();//单例缓存管理  
    }  

    public static void setCacheManager(CacheManager cacheManager) { 
        EhCacheManager.cacheManager = cacheManager;  
    }  


    public QueryMsgTestDao getQueryMsgTestDao() {
        return queryMsgTestDao;
    }

    public void setQueryMsgTestDao(QueryMsgTestDao queryMsgTestDao) {
        this.queryMsgTestDao = queryMsgTestDao;
    }

    //添加新缓存  
    public static void addCacheByName(String cacheName){  
        if(cacheName==null||cacheName.trim().equals("")){  
            logger.error("cacheName is null"); 
        }else{  
            if(getCacheManager().getCache(cacheName.trim())!=null){  
                getCacheManager().removeCache(cacheName.trim());  
            }  
            getCacheManager().addCache(cacheName.trim());  
            logger.info(cacheName+ "is add complete");  
        }  
    }

    //得到cache对象  
    public static Cache getCacheByName(String cacheName){  
        Cache cache=null;  
        if(cacheName==null||cacheName.trim().equals("")){  
            logger.error("cacheName is null");   
        }else{  
            if(getCacheManager().getCache(cacheName.trim())!=null){  
                cache=getCacheManager().getCache(cacheName.trim());  
            }else{
                logger.error("cacheName is not existent");
            }
        }            
        return cache;  
    }  

    //往缓存中添加元素  
    public static void putElementToCache(String cacheName,String elementKey,Object elementValue){  
        Cache cache=null;  
        if(cacheName==null||cacheName.trim().equals("")){  
            logger.error("Failed to add cache element,cacheName is null");  
        }else if(StringUtils.isEmpty(elementKey)||StringUtils.isEmpty(elementValue)){  
            logger.error("Failed to add cache element,elementKey or elementValue is null");  
        }else{  
            if(getCacheByName(cacheName.trim())!=null){//缓存存在  
                cache=getCacheByName(cacheName.trim());  
            }else{//缓存不存在  
                addCacheByName(cacheName.trim());  
                cache=getCacheByName(cacheName.trim());  
            }  
            //对cache对象添加Element  
            Element element=null;  
            if(cache.get(elementKey.trim())!=null){  
                cache.remove(elementKey.trim());  
            }  
            element=new Element(elementKey.trim(),elementValue);  
            cache.put(element);  
            logger.info("add element:"+elementKey+"  success!");  
        }           
    } 

    //从缓存中获取指定key的值  
    public static Object getElementValueFromCache(String cacheName,String elementKey){  
        Object result=null;  
        Cache cache=null;  
        if(cacheName==null||cacheName.trim().equals("")){  
            logger.error("Failed to get cache element,cacheName is null");  
        }else if(elementKey==null){  
            logger.error("Failed to get cache element,elementKey is null");  
        }else{  
            if(getCacheByName(cacheName.trim())!=null){//缓存存在  
                cache=getCacheByName(cacheName.trim());                   
                Element element=null;  
                if(cache.get(elementKey.trim())!=null){  
                    element=cache.get(elementKey.trim());  
                    if(element.getObjectValue()==null){  
                        logger.error("The value of "+elementKey+" in the cache is empty");//缓存中的 elementKey的value为空 
                    }else{  
                        result=element.getObjectValue();  
                    }  
                }else{  
                    logger.error("There is no:"+elementKey+"  in the cache"); //缓存中无elementKey
                }  
            }else{//缓存不存在  
                logger.error("Failed to get cache element,The element:"+cacheName+" in the cache is empty");  
            }  
        }            
        return result;  
    }  

    /** 
     * 获取缓存的Keys 
     *  
     * @param cacheName 
     * @return 
     */  
    @SuppressWarnings("unchecked")  
    public static List<String> getKeys(String cacheName) {  
        Ehcache cache = getCacheManager().getEhcache(cacheName);  
        return (List<String>) cache.getKeys();  
    }  

    /** 
     * 把所有cache中的内容删除,但是cache对象还是保留. 
     * Clears the contents of all caches in the CacheManager, 
     *  but without removing any caches. 
     */  
    public static void clearAllFromCacheManager(){  
        if(getCacheManager()!=null){  
            getCacheManager().clearAll();  
            logger.info("CacheManager was clearAll...");  
        }  
    } 

    /** 
     * 删除指定对象 
     *  
     * @param cacheName 
     * @param key 
     * @return 
     */  
    public static boolean remove(String cacheName, String key) {  
        return getCacheManager().getCache(cacheName).remove(key);  
    } 
    /** 
     * 把所有cache对象都删除。慎用! 
     * Removes all caches using removeCache(String) for each cache. 
     */  
    public static void removalAllFromCacheManager(){  
        if(getCacheManager()!=null){  
            getCacheManager().removalAll();  
            logger.info("CacheManager was removalAll...");  
        }  
    }   

    /** 
     * 获取缓存大小 
     *  
     * @param cacheName 
     * @return 
     */  
    public static int getSize(String cacheName) {  
        return getCacheManager().getCache(cacheName).getSize();  
    } 

    //不用缓存时,要关闭,不然会占用cpu和内存资源。  
    public static void shutdownCacheManager(){  
        if(getCacheManager()!=null){  
            getCacheManager().shutdown();  
            logger.info("CacheManager was shutdown...");  
        }  
    } 


    /**
     * 测试用
     * @param cache
     */

    //打印方法1,为了测试用
    @SuppressWarnings("unused")
    public static void printCache(Cache cache){  
        logger.info("缓存状态: "+cache.getStatus().toString());
        if(cache==null){
            logger.info("cache is null,no print info.");
        }else if(cache.getStatus().toString().equals(Status.STATUS_UNINITIALISED)){  
            logger.info("缓存状态: 未初始化"+cache.getStatus().toString());  
        }else if(cache.getStatus().toString().equals(Status.STATUS_SHUTDOWN)){  
            logger.info("缓存状态: 已关闭"+cache.getStatus().toString());  
        }else if(cache.getStatus().toString().trim().equals(Status.STATUS_ALIVE)){
            System.out.println("进入缓存取数据");
            if(cache.getKeys().size()==0){  
                logger.info(cache.getName()+" exits,but no value.");  
            }else{  
                for(int i=0;i<cache.getKeys().size();i++){  
                    Object thekey=cache.getKeys().get(i);  
                    Object thevalue=cache.get(thekey);  
                    logger.info(cache.getName()+"--"+i+",key:"+thekey.toString()+",value:"+thevalue.toString());  
                }  
            }  
        }   
    }  

    //打印方法2,为了测试用  
    public static void printCacheByName(String cacheName){  
        if(cacheName==null||cacheName.trim().equals("")){  
            logger.info("cacheName is null,no print info.");  
        }else{  
            if(getCacheManager().getCache(cacheName.trim())!=null){  
                Cache cache=getCacheManager().getCache(cacheName.trim());  
                printCache(cache);  
            }else{  
                logger.info(cacheName+" --null");  
            }  
        }     
    } 

    public static void main(String[] sdfsf){  
        Cache cache1=EhCacheManager.getCacheByName(EhCacheManager.CACHE_MYCOMMONCACHE);  
        printCache(cache1);  

        EhCacheManager.putElementToCache(EhCacheManager.CACHE_MYCOMMONCACHE, "111", "111haah");  
        EhCacheManager.putElementToCache(EhCacheManager.CACHE_MYCOMMONCACHE, "222", "222haah");  
        EhCacheManager.putElementToCache(EhCacheManager.CACHE_MYCOMMONCACHE, "333", "333haah");  

        printCache(cache1);  

        EhCacheManager.putElementToCache(EhCacheManager.CACHE_MYCOMMONCACHE, "111", "111的新值。");  

        logger.info(EhCacheManager.getElementValueFromCache(EhCacheManager.CACHE_MYCOMMONCACHE, "111"));  
        printCache(cache1);  

        clearAllFromCacheManager();  
        printCache(cache1);  

        removalAllFromCacheManager();  
        printCache(cache1);  

        shutdownCacheManager();  
    } 

    ///上面是对缓存操作的Demo,实际使用逻辑需要改变 /  

    ///以下是web环境下对字典表的缓存操作/  

    //得到字典表cache对象("cacheTest")  
    public Cache getMyCommonCache(){  
        Cache cache=null;  
        if(getCacheManager().getCache(EhCacheManager.CACHE_MYCOMMONCACHE)!=null){  
            cache=getCacheManager().getCache(EhCacheManager.CACHE_MYCOMMONCACHE);  
        }else{//如果缓存没有了,这里直接添加,因为在实际中我们不可能告诉应用没有了这个缓存就返回了。  
            //而是应该先去查数据,放入缓存,然后再从缓存中取数据。  
            //当然,如果缓存有数据,那就直接取数据就行了。  
            getCacheManager().addCache(EhCacheManager.CACHE_MYCOMMONCACHE);  
        }  
        return cache;  
    }    

    //从cacheTest缓存中获取字典表数据(这里只是简单的把所有值取出来了,实际应用可以更加细化)  
    public List<UserTest> getDictionaryListFromMyCommonCache(String codeNo){  
        codeNo=(codeNo==null||codeNo.trim().equals(""))?"":codeNo.trim();  
        List<UserTest> dictionaryList=null;  
        Cache cache=getMyCommonCache();//字典表公用缓存  
        Element element=null;  
        if(cache.get(EhCacheManager.ELEMENT_MYCOMMONCACHE_DICTIONARY)!=null){  
            element=cache.get(EhCacheManager.ELEMENT_MYCOMMONCACHE_DICTIONARY);                
            if(element.getObjectValue()==null){//值为空,需要从新添加到缓存  
                List<UserTest> userList=this.getQueryMsgTestDao().queryUserByName(codeNo);//查询  
                if(userList!=null&&userList.size()!=0){  
                    MyCacheObject myCacheObject = new MyCacheObject(userList);  
                    element=new Element((Serializable)EhCacheManager.ELEMENT_MYCOMMONCACHE_DICTIONARY,(Serializable)myCacheObject);  
                    //java.io.NotSerializableException:  
                    cache.put(element);  
                    logger.info("缓存中的字典表元素为空,重新查询添加..");  
                }  
                dictionaryList=userList;  
            }else{//有值  
                MyCacheObject myObj=(MyCacheObject)element.getObjectValue();  
                dictionaryList=(List<UserTest>)myObj.getObject();  
                logger.info("缓存中存在字典表数据,直接获取到。");  
            }  
        }else{//获取Element空,需要从新添加到缓存  
            List<UserTest> userList=this.getQueryMsgTestDao().queryUserByName(codeNo);//查询  
            if(userList!=null&&userList.size()!=0){  
                MyCacheObject myCacheObject = new MyCacheObject(userList);  
                element=new Element((Serializable)EhCacheManager.ELEMENT_MYCOMMONCACHE_DICTIONARY,(Serializable)myCacheObject);  
                cache.put(element);  
                logger.info("缓存中的字典表元素为空,重新查询添加......");  
            }  
            dictionaryList=userList;  
        }  
        return dictionaryList;  
    }


    /** 
     * 有时需要强制从数据库查询最新的实际数据,所以需要刷新缓存,保证数据的实时性。 
     * 这里的刷新是指把缓存中所有Element清除 
     */  
    public void refreshDictionaryListInMyCommonCache(){  
        Cache cache=getMyCommonCache();//字典表公用缓存  
        Element element=null;  
        if(cache.get(EhCacheManager.ELEMENT_MYCOMMONCACHE_DICTIONARY)!=null){  
            for(int i=0;i<cache.getKeys().size();i++){  
                cache.remove(cache.getKeys().get(i));  
            }  
        }  
        //如果某些缓存刷新后需要马上填充,就可以像下面直接放数据  
//      if(this.getMyEhcacheDao().querydictionaryByCodeNo("")!=null){  
//          List list=this.getMyEhcacheDao().querydictionaryByCodeNo("");//查询  
//          MyCacheObject myCacheObject = new MyCacheObject(list);  
//          element=new Element((Serializable)MyEhcacheManager.ELEMENT_MYCOMMONCACHE_DICTIONARY,(Serializable)myCacheObject);  
//          cache.put(element);  
//          System.out.println("已经强制刷新字典表缓存。。。");  
//      }  
        System.out.println("已经强制清空字典表所有缓存。。。");  
    }  

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值