SpringBoot集成ehcache

来源:互联网 发布:mt4软件使用 编辑:程序博客网 时间:2024/06/08 19:49

1.场景还原

    近日,由于项目中涉及到相关数据的缓存,之前也写过redis缓存的博客;但是笔者认为ehcache与之比较,配置简单,也容易上手,于是今天介绍一下springboot工程中如何集成EhCache

2.实现方案

①导入ehcache相关依赖

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-cache</artifactId>  <version>1.4.2.RELEASE</version></dependency><!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache --><dependency>  <groupId>net.sf.ehcache</groupId>  <artifactId>ehcache</artifactId>  <version>2.8.3</version></dependency>
②在springboot启动类配置支持缓存配置@EnableScheduling

@SpringBootApplication@MapperScan(basePackages = "com.cckj.dao", markerInterface =Mapper.class)@EnableCaching@EnableSchedulingpublic class Application extends SpringBootServletInitializer {    private static Logger logger = LoggerFactory.getLogger(Application.class);    @Override    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {        return builder.sources(Application.class);    }    public static void main(String[] args) {        SpringApplication.run(Application.class, args);        logger.info("My Spring Boot Application Started");    }}
③在resources目录下创建ehcache.xml文件

<?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">    <diskStore path="java.io.tmpdir/ehcache"/>    <!-- 设定缓存的默认数据过期策略 -->    <defaultCache            maxElementsInMemory="1000"            eternal="false"            overflowToDisk="true"            timeToIdleSeconds="10"            timeToLiveSeconds="20"            diskPersistent="false"            diskExpiryThreadIntervalSeconds="120"/>    <cache name="users"           maxElementsInMemory="1000"           eternal="false"           overflowToDisk="true"           timeToIdleSeconds="1"           timeToLiveSeconds="20"/></ehcache>

cache元素的属性:   

name:缓存名称                 

maxElementsInMemory:内存中最大缓存对象数                 

maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大                 

eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false               

overflowToDisk:true表示当内存缓存的对象数目达到了maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。注       意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。                 

diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。              

diskPersistent:是否缓存虚拟机重启期数据                 

diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒    

timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态                 

timeToLiveSeconds:设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,如果处于缓存中的时间超过了    timeToLiveSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义    

memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。 

④在application.properities中配置

#ehcache配置spring.cache.jcache.config=classpath:ehcache.xml
⑤在实现类中实现缓存注解配置

@Override@Cacheable(value = "users", key = "#param")public String getTimestamp(String param) {    Long timestamp = System.currentTimeMillis();    return timestamp.toString();}

这里的users就是前面ehcache.xml中的cache的name;

在测试之前先确认下cache的过期时间

<!-- 设定缓存的默认数据过期策略 --><defaultCache        maxElementsInMemory="1000"        eternal="false"        overflowToDisk="true"        timeToIdleSeconds="10"        timeToLiveSeconds="20"        diskPersistent="false"        diskExpiryThreadIntervalSeconds="120"/><cache name="users"       maxElementsInMemory="1000"       eternal="false"       overflowToDisk="true"       timeToIdleSeconds="10"       timeToLiveSeconds="20"/>
对应users的cache过期时间timeToIdleSeconds为10s,也就是超过10后就缓存自动清除

⑥测试类:

@Testpublic void test1() throws InterruptedException {  String first =  userService.getTimestamp("param");    System.out.println("第一次调用:"+first);    Thread.sleep(5000);    String second =  userService.getTimestamp("param");    System.out.println("第二次调用:"+second);    Thread.sleep(30000);    String third =  userService.getTimestamp("param");    System.out.println("第三次调用:"+third);}

效果图:


第一次与第二次结果相同,第三次与前两次都不同; 因为第二次还在cache的缓存时间10s内,然而第三次却不在cache的缓存的时间内,所以与之前两次都不同。

3.ehcache注解详解

@CacheConfig:主要用于配置该类中会用到的一些共用的缓存配置。在这里@CacheConfig(cacheNames = "users"):配置了该数据访问对象中返回的内容将存储于名为users的缓存对象中,我们也可以不使用该注解,直接通过@Cacheable自己配置缓存集的名字来定义。

@Cacheable:配置了findByName函数的返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。该注解主要有下面几个参数:

 valuecacheNames:两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了

key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = "#p0"):使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档

condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有当第一个参数的长度小于3的时候才会被缓存,若做此配置上面的AAA用户就不会被缓存,读者可自行实验尝试。

unless:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于condition参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断。

keyGenerator:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定。需要注意的是:该参数与key是互斥的

cacheManager:用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用

cacheResolver:用于指定使用那个缓存解析器,非必需。需通过org.springframework.cache.interceptor.CacheResolver接口来实现自己的缓存解析器,并用该参数指定。

除了这里用到的两个注解之外,还有下面几个核心注解:

@CachePut:配置于函数上,能够根据参数定义条件来进行缓存,它与@Cacheable不同的是,它每次都会真是调用函数,所以主要用于数据新增和修改操作上。它的参数与@Cacheable类似,具体功能可参考上面对@Cacheable参数的解析

@CacheEvict:配置于函数上,通常用在删除方法上,用来从缓存中移除相应数据。除了同@Cacheable一样的参数之外,它还有下面两个参数:allEntries:非必需,默认为false。当为true时,会移除所有数据beforeInvocation:非必需,默认为false,会在调用方法之后移除数据。当为true时,会在调用方法之前移除数据。

好了,今天的ehcache就到此结束,我是张星,欢迎加入博主技术交流群,群号:313145288