SpringBoot整合Ehcache3

2018-09-27 23:42:51

SpringBoot整合Ehcache3

先谈谈springboot-cache

  • SpringBoot 也对缓存提供了开箱即用的starter
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-cache</artifactId>
  4. </dependency>
  • 它支持使用的缓存实现

    • SimpleCacheManager,使用简单的 Collection来缓存数据
    • ConcurrentMapCache,使用简单的 ConcurrentMap来缓存数据
    • EhCacheCacheManager,使用Ehcache缓存数据
    • RedisCacheManager,使用Redis来缓存数据
  • Ehcache的理由

    内存级别的缓存肯定是性能最高的,但是服务器内存太珍贵了,我舍不得做缓存(土豪无视)
    其次性能最好的应该是硬盘,Ehcache支持缓存数据到硬盘(它也支持内存级别的缓存,Ehcache3还支持了分布式的缓存)
    最后是redis这种NOSQL服务,它也是缓存于内存,序列化到硬盘,但是要通过网络IO读取,性能最低

整合Ehcache3

导入依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-cache</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.ehcache</groupId>
  7. <artifactId>ehcache</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>javax.cache</groupId>
  11. <artifactId>cache-api</artifactId>
  12. </dependency>
  • javax.cache,是java的一个缓存规范,而ehcache是该规范的实现

配置

  1. spring.cache.type=jcache
  2. spring.cache.jcache.config=classpath:ehcache/ehcache.xml
  • spring.cache.type
    • 指定spring使用哪种缓存,支持以下参数
      • Generic
      • JCache (JSR-107)
      • EhCache 2.x
      • Hazelcast
      • Infinispan
      • Redis
      • Guava
      • Simple
  • spring.cache.jcache.config指定Ehcache的配置文件(最后有简单讲解)

@Configuration 激活缓存

  1. import org.springframework.cache.annotation.EnableCaching;
  2. import org.springframework.context.annotation.Configuration;
  3. @Configuration
  4. @EnableCaching
  5. public class CacheConfiguration {
  6. }

缓存加持 @Cacheable

  • 标识在方法上,如果存在缓存,直接返回,不存在则调用方法获取计算结果,存入缓存
  • 当标记在一个类上时则表示该类所有的方法都是支持缓存的
  • 它有很多属性,这里仅仅列举部分

    • cacheNames
      • 指定缓存使用的仓库(我理解为仓库),人以类聚物以群分
    • key

      • 指定缓存的key如果方法没有参数,则使用0作为key
      • 如果只有一个参数,且未定义key,使用该参数作为key
      • 如果又多个参数,且未定义key,使用包含所有参数的hashCode作为key
      • 支持使用SpringEL表达式

        1. @Cacheable(value = "user", key = "#user.id") //使用user的id作为key
        2. public User fun(User user){}
        3. @Cacheable(cacheNames="users", key="#map['user'].toString()") //使用map里面key为`user`的`toString()`结果作为key
        4. public User fun(Map<String, Object> map){}
        5. @Cacheable(cacheNames="users", key="'user'") //使用字符串'user'作为key
        6. public User fun(Map<String, Object> map){}
    • unless

      • 该属性是一个SpEL表达式,如果表达式的结果为true,则不会执行缓存

        1. /**
        2. 如果方法返回null,也会被认为是一种返回值,null也会被缓存,有些时候这不是我们希望的
        3. 通过该属性来控制,禁止缓存null
        4. #result 可以引用到方法的结果值,通过 == null判断,如果为true,那么就不缓存
        5. */
        6. @Cacheable(value = "post",unless="#result == null")
    • sync
      • bool值,默认为 false
      • 如果该值为true,那么在缓存不存在的时候,仅仅只有一个线程能访问到该方法,其他线程对该方法的访问全部被阻塞,直到缓存可用
      • 设置为true,可以防止在并发较大的时候,缓存击穿而导致多个请求直接打到DB。

缓存删除@CacheEvict

  • 标注在需要清除缓存元素的方法或类上的
  • 当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作
  • 属性
    • cacheNames
      • 指定缓存使用的仓库
    • key
      • @Cacheable一样,指定要删除的缓存key
    • allEntries
      • bool值默认false,是否删除该仓库下的所有缓存数据
    • beforeInvocation
      • bool值默认false,删除除操作默认是在对应方法成功执行之后触发的
      • 即方法如果因为抛出异常而未能成功返回时也不会触发清除操作
      • 该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素

批量操作@Caching

  • 组合注解,把多个注解整合到一个上
  • 属性有
    • Cacheable[] cacheable() default {};
    • CachePut[] put() default {};
    • CacheEvict[] evict() default {};
  1. //把多个CacheEvict整合到该注解,标识在函数,调用该函数的时候,会清空a,b,c,d四个仓库的所有缓存
  2. @Caching(evict = {
  3. @CacheEvict(value = "a",beforeInvocation = true,allEntries = true),
  4. @CacheEvict(value = "b",beforeInvocation = true,allEntries = true),
  5. @CacheEvict(value = "c",beforeInvocation = true,allEntries = true),
  6. @CacheEvict(value = "d",beforeInvocation = true,allEntries = true)
  7. })

总是执行缓存@CachePut

  • 不论怎么样,都会把方法返回值放入缓存中
  • 它标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中
  • 属性跟@Cacheable一样

使用自定义注解

  • spring允许在配置可缓存的方法时使用自定义的注解
  • 前提是自定义的注解上必须使用对应的缓存注解进行标注
  1. @Target({ElementType.TYPE, ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Cacheable(value="users") //在自定义注解上标识 缓存注解
  4. public @interface MyCacheable {
  5. }

使用代码操作缓存,需要从IOC中获取Ehcache的实例

  1. import javax.cache.Cache;
  2. import javax.cache.CacheManager;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Component;
  5. @Component
  6. public class Main {
  7. //该接口是javax.cache的接口,spring会注入它的是实现(Ehcache)
  8. @Autowired
  9. private CacheManager cacheManager;
  10. public void foo() {
  11. //根据仓库名称,Key类型,value类型获取 cache对象
  12. Cache<String,String> cache = this.cacheManager.getCache("user",String.class,String.class);
  13. //通过cache对象操作缓存
  14. cache.get("1"); //获取key为1的缓存
  15. cache.remove("1"); //删除key为1的缓存
  16. cache.containsKey("1"); //判断是否包含key为1的缓存
  17. ...
  18. }
  19. }

Ehcache3的配置文件简单介绍

  • 该文件就是:spring.cache.jcache.config=classpath:ehcache/ehcache.xml
  • Ehcache的功能还是比较强大,配置也比较复杂,可以参考官网
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  3. xmlns='http://www.ehcache.org/v3'
  4. xsi:schemaLocation="http://www.ehcache.org/v3
  5. http://www.ehcache.org/schema/ehcache-core.xsd">
  6. <!-- 缓存到磁盘使用的目录 -->
  7. <persistence directory="c:\ehcache"/>
  8. <!-- 定义一个缓存仓库,alias也就是 @Cacheable 的 cacheNames 属性 -->
  9. <cache alias="user">
  10. <!--指定key的类型,@Cacheable 指定的key类型-->
  11. <key-type>java.lang.Integer</key-type>
  12. <!--指定返回类型,也就是方法返回的数据类型-->
  13. <value-type>com.foo.User</value-type>
  14. <!--
  15. 指定缓存的过期策略,tti,ttil,none。以及他们的单位时,分,秒,日
  16. 这里的配置表示,在缓存超过1H后没使用过,即删除
  17. -->
  18. <expiry>
  19. <tti unit="hours">1</tti>
  20. </expiry>
  21. <!--
  22. 指定缓存的缓存位置,可以指定堆内存,堆外内存,磁盘,以及他们最大使用的空间
  23. 这里配置表示仅仅使用磁盘缓存
  24. -->
  25. <resources>
  26. <disk unit="GB" persistent="true">10</disk>
  27. </resources>
  28. </cache>
  29. </config>

0
1
0

添加评论

正在回复:
取消
5
0
1
0