SpringMVC+mybatis+maven+Ehcache缓存实现

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

缓存主要可分为二大类: 

一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;  

二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查.

一、EhCache缓存系统简介

EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。

EhCache 应用架构图,下图是 EhCache 在应用程序中的位置:

  EhCache 的主要特性有: 

    1. 快速、精干;

    2. 简单;

    3. 多种缓存策略;

    4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题;

    5. 缓存数据会在虚拟机重启的过程中写入磁盘;

    6. 可以通过 RMI、可插入 API 等方式进行分布式缓存;

    7. 具有缓存和缓存管理器的侦听接口;

    8. 支持多缓存管理器实例,以及一个实例的多个缓存区域;

    9. 提供 Hibernate 的缓存实现;

二、maven添加Ehcache核心包 

在pom.xml配置文件里,添加

  <!--ehcache 相关包 -->
   <dependency>
       <groupId>net.sf.ehcache</groupId>
       <artifactId>ehcache</artifactId>
       <version>2.7.5</version>
   </dependency>
   <dependency>
       <groupId>com.googlecode.ehcache-spring-annotations</groupId>
       <artifactId>ehcache-spring-annotations</artifactId>
       <version>1.2.0</version>
   </dependency>

三、添加配置文件

在资源文件夹下(通常是src/main/resources/META-INF) 添加 applicationContext-ehcache.xmlehcache.xml

1、applicationContext-ehcache.xml内容如下:

<?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:c="http://www.springframework.org/schema/c" 
xmlns:cache="http://www.springframework.org/schema/cache" xmlns:context="http://www.springframework.org/schema/context" 
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" 
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task" 
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 开启spring缓存 -->
    <cache:annotation-driven cache-manager="cacheManager" />
    <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:META-INF/ehcache.xml"/>
    </bean>
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="cacheManagerFactory"/>
    </bean>

</beans>

  这里是开启spring缓存   

2、ehcache.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
 monitoring="autodetect" dynamicConfig="true">

    <diskStore path="${java.io.tmpdir}/${system.project_name}/cache" />
    <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" 
          maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
    <cache name="baseCache" maxElementsInMemory="200" maxElementsOnDisk="1000" eternal="false" overflowToDisk="true" diskSpoolBufferSizeMB="20"
       timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU" />

</ehcache>

  这里是添加缓存策略

说明:

   1、java.io.tmpdir 所指地址:   

 操作系统不同 这个系统属性所表示的目录也不同
On Windows: java.io.tmpdir:[C:\DOCUME~1\joshua\LOCALS~1\Temp\]

On Solaris: java.io.tmpdir:[/var/tmp/]

On Linux: java.io.tmpdir: [/tmp]

On Mac OS X: java.io.tmpdir: [/tmp]

    The default temporary-file directory is specified by the system property java.io.tmpdir. On UNIX systems the default value of this property is typically "/tmp" or "/var/tmp"; on Microsoft Windows systems it is typically "c:\temp". A different value may be given to this system property when the Java virtual machine is invoked, but programmatic changes to this property are not guaranteed to have any effect upon the the temporary directory used by this method.

To specify the java.io.tmpdir System property, you can invoke the JVM as follows:

java -Djava.io.tmpdir=/path/to/tmpdir

By default this value should come from the TMP environment variable on Windows systems

2、数据含义

    name:Cache的唯一标识
    maxElementsInMemory:内存中最大缓存对象数
    maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大
    eternal:Element是否永久有效,一但设置了,timeout将不起作用
    overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
    timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大
    timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大  
    diskPersistent:是否缓存虚拟机重启期数据  
    diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒
    diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
    memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)
  或是LFU(较少使用)

四、DAO层做配置

    import org.springframework.cache.CacheManager;
  import org.springframework.cache.annotation.Cacheable;
    .....        
  @TriggersRemove(cacheName="baseCache",removeAll=true)
    public Entity save(Entity entity) throws CrudException {
        return entity;
    }

    @TriggersRemove(cacheName="baseCache",removeAll=true)
    public Entity update(Entity entity) throws CrudException {
        return entity;
    }

    @TriggersRemove(cacheName="baseCache",removeAll=true)
    public void del(Entity entity) throws CrudException {
            }

    @Cacheable(value="baseCache", key = "'findAll'")    
    public List<Entity> findAll() throws SearchException {
        return list;
    }

@Cacheable(value="baseCache", key = "'findAll'")

这个注解就是做到缓存数据,cacheName对应ehcache.xml 中配置

 @TriggersRemove(cacheName="baseCache",removeAll=true)

这个注解的作用就是当数据发生变化的时候清除缓存,做到数据同步

扩展:@Cacheable可以指定三个属性,value、key和condition。

1、@Cacheable("cache1")、@Cacheable({"cache1", "cache2"})//Cache是发生在cache1和cache2上的

    value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。

2、@Cacheable(value="users", key="#user.id")、@Cacheable(value="users", key="#p0")

    key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。我们这里先来看看自定义策略,自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性

  3、@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")

有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。以上下示例表示只有当user的id为偶数时才会进行缓存。

  4、@CachePut("users")

    在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

       @CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。

  5、@CacheEvict(value="users", allEntries=true)

  allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。

  6、@CacheEvict(value="users", beforeInvocation=true)

    清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

  7、@Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),

         @CacheEvict(value = "cache3", allEntries = true) })

public User find(Integer id) {

return null;

     }

   @Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。

如何知道有没生效:查看sql执行日志

参考:

http://www.blogjava.net/zzzlyr/articles/343234.html

http://blog.goyello.com/2010/07/29/quick-start-with-ehcache-annotations-for-spring/

http://haohaoxuexi.iteye.com/blog/2123030

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

c#实现打印功能

2632
来自专栏java 成神之路

使用 NIO 实现 echo 服务器

4537
来自专栏Golang语言社区

【Golang语言社区】GO1.9 map并发安全测试

var m sync.Map //全局 func maintest() { // 第一个 YongHuomap := make(map[st...

4688
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2697
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2000
来自专栏大内老A

The .NET of Tomorrow

Ed Charbeneau(http://developer.telerik.com/featured/the-net-of-tomorrow/) Exciti...

30910
来自专栏C#

DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱。不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬。(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...)...

4828
来自专栏魂祭心

原 canvas绘制clock

4034
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3095
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2506

扫码关注云+社区