SpringBootspringboot程序员

springcache

2017-09-29  本文已影响41人  小鱼嘻嘻
在springcache之前

在没有使springcache之前我们使用缓存的方式是这样的:

 Map<StoreKey, List<SpecialHall>> keyListHashMap = Maps.newHashMap();
        DateTime dt = new DateTime().withHourOfDay(2).plusDays(1);
        DateTime now = DateTime.now();
        int toTwo = (int) (dt.getMillis() - now.getMillis()) / 1000;
        List<SpecialHall> resList = Lists.newArrayList();
        for (Integer cinemaId : cinemaIds) {
            StoreKey storeKey = new StoreKey(CacheConstants.GDATA_STRING, String.format(CacheConstants.GATEWAY_SPECIALS_BY_CINEMAID, cinemaId));
            keyListHashMap.put(storeKey, resList);
            returnTocMap.put(cinemaId, transToTSpecialHallToApp(resList));
        }
        redisStoreClient.multiSet(keyListHashMap, toTwo);

这段代码我刚开始看的时候也觉得没问题,还觉得写的挺好的(因为是我写的偷笑),等我看到了springcache之后我觉得这段代码就不是那么的优雅了,总体来说就是代码的处理逻辑和缓存耦合在一起,降低了代码的可读性,不利于后期人员的维护;还有就是缓存切换的话成本很大,需要改动的地方比较多,风险成本比较高。

在springcache之后
springcache是什么?

首先,要明白springcache是一种解决缓存的方案,而不是一种具体的缓存方式(类似的Redis,memcache,ehcache等等)。

springcache的相关配置

pom配置:
这里需要注意spring应该是3.1+

<dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.8.3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>

springcache相关xml配置

 <!-- ehcache -->
    <cache:annotation-driven cache-manager="ehcacheManager"/>
    <!-- 声明cacheManager -->
    <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="ehcacheManagerFactory" />
    </bean>
    <!-- cacheManager工厂类,指定ehcache.xml的位置 -->
    <bean id="ehcacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache.xml" />
    </bean>

还需要配置具体的缓存:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false">
    <diskStore path="/Users/yuxi/work/myoschina/tmpdir"/>
    <!--
    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"
            timeToIdleSeconds="60"
            timeToLiveSeconds="60"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="true"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
    />
    <cache name="dbCache" maxElementsInMemory="10000" eternal="false"
           timeToLiveSeconds="1800" overflowToDisk="false" diskPersistent="true"/>
</ehcache>
springcache的相关代码实现
package com.yuxi.cache;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 * Created by yuxi on 2017/9/28.
 */
@Service("cacheService")
public class CacheService {

    @Cacheable(value = "dbCache", key = "'info_' + #id")
    public Info getInfo(Integer id) {
        System.out.println("from cache");
        return getDb(id);
    }

    private Info getDb(Integer id) {
        System.out.println("from db" + id);
        return new Info(id);
    }


    @CachePut(value = "dbCache", key = "'info_' + #id")
    public Info getInfo2(Integer id) {
        System.out.println("from cache put");
        return getDb(id);
    }


    @CacheEvict(value = "dbCache", key = "'info_' + #id")
    public boolean delete(Integer id) {
        System.out.println("delete");
        return true;
    }
}

相关测试类

package com.yuxi.main;

import com.yuxi.cache.CacheService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by yuxi on 2017/8/5.
 */
public class KnightMain {
    public static void main(String[] args) {
        // spring 应用上下文
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("knight.xml");
   
        CacheService cacheService = (CacheService) applicationContext.getBean("cacheService");
        cacheService.getInfo(1);
        cacheService.getInfo(1);
        cacheService.getInfo(1);
        cacheService.getInfo(1);
        cacheService.getInfo(1);

        cacheService.getInfo2(1);
        cacheService.getInfo2(1);
        cacheService.getInfo2(1);
        cacheService.delete(1);
    }
}

相关的测试结果为:

from cache
from db1
from cache put
from db1
from cache put
from db1
from cache put
from db1
delete
springcache的相关注解说明:

三图胜过万言,图片来自郭老师的wiki,不要问我郭老师是谁?他是一个传说。

郭老师的wiki 郭老师的wiki 郭老师的wiki

相关代码可以参考:springcache

上一篇 下一篇

猜你喜欢

热点阅读