第七篇:Spring Boot集成Spring Cache

版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接 ,博主地址:https://blog.csdn.net/mr_chenjie_c。 https://blog.csdn.net/Mr_Chenjie_C/article/details/84927310

为了提高性能,减少数据库的压力,使用缓存是非常好的手段之一。因此本文讲解 Spring Boot 如何集成缓存管理。

声明式缓存

Spring 定义 CacheManager 和 Cache 接口用来统一不同的缓存技术。例如 JCache、 EhCache、 Hazelcast、 Guava、 Redis 等。在使用 Spring 集成 Cache 的时候,我们需要注册实现CacheManager 的 Bean。

几个重要概念&缓存注解

在这里插入图片描述

@Cacheable/@CachePut/@CacheEvict 主要的参数

在这里插入图片描述

SpEL上下文数据

在这里插入图片描述

注意:

  1. 当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。 如
@Cacheable(key = "targetClass + methodName +#p0")
  1. 使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。 如:
@Cacheable(value="users", key="#id")
@Cacheable(value="users", key="#p0")

SpEL提供了多种运算符

在这里插入图片描述

Spring Boot默认集成CacheManager

Spring Boot 为我们自动配置了多个 CacheManager 的实现。
在这里插入图片描述
Spring Boot 为我们自动配置了 JcacheCacheConfiguration、 EhCacheCacheConfiguration、HazelcastCacheConfiguration、GuavaCacheConfiguration、RedisCacheConfiguration、SimpleCacheConfiguration 等。

默认使用 ConcurrenMapCacheManager

在我们不使用其他第三方缓存依赖的时候,springboot自动采用ConcurrenMapCacheManager作为缓存管理器。

环境依赖

Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。本文使用Ehcache,在pom文件引入spring-boot-starter-cache和ehcache环境依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>

yml配置

需要说明的是config: classpath:/ehcache.xml可以不用写,因为默认就是这个路径。但ehcache.xml必须有。

spring:  
  cache:
    type: ehcache
    ehcache:
      config: classpath:/ehcache.xml

ehcache.xml

<ehcache>

    <!--
        磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存
        path:指定在硬盘上存储对象的路径
        path可以配置的目录有:
            user.home(用户的家目录)
            user.dir(用户当前的工作目录)
            java.io.tmpdir(默认的临时目录)
            ehcache.disk.store.dir(ehcache的配置目录)
            绝对路径(如:d:\\ehcache)
        查看路径方法:String tmpDir = System.getProperty("java.io.tmpdir");
     -->
    <diskStore path="java.io.tmpdir" />

    <!--
        defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理
        maxElementsInMemory:设置了缓存的上限,最多存储多少个记录对象
        eternal:代表对象是否永不过期 (指定true则下面两项配置需为0无限期)
        timeToIdleSeconds:最大的发呆时间 /秒
        timeToLiveSeconds:最大的存活时间 /秒
        overflowToDisk:是否允许对象被写入到磁盘
        说明:下列配置自缓存建立起600秒(10分钟)有效 。
        在有效的600秒(10分钟)内,如果连续120秒(2分钟)未访问缓存,则缓存失效。
        就算有访问,也只会存活600秒。
     -->
    <defaultCache maxElementsInMemory="10000" eternal="false"
                  timeToIdleSeconds="600" timeToLiveSeconds="600" overflowToDisk="true" />

    <cache name="userCache" maxElementsInMemory="10000" eternal="false"
                  timeToIdleSeconds="120" timeToLiveSeconds="600" overflowToDisk="true" />

</ehcache>

开启缓存支持

在 Spring Boot 中使用 @EnableCaching 开启缓存支持。

@EnableCaching
@SpringBootApplication
public class SpringbootCacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootCacheApplication.class, args);
    }
}

Service层

创建一个服务类,添加@CacheConfig(cacheNames = {“userCache”})注解设置ehcache的名称,这个名称必须在ehcache.xml已配置 。

@Service
@CacheConfig(cacheNames = {"userCache"})
public class UserService {

}

首先,我们先来讲解下 @Cacheable 注解。@Cacheable 在方法执行前 Spring 先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放进缓存。此处的value不是必需的,你可以使用@CacheConfig(cacheNames = {“userCache”})注解来统一指定value的值,这时可省略value,如果你在方法依旧写上了value,那么依然以方法的value值为准。注意:此处的User实体类一定要实现序列化,否则会报java.io.NotSerializableException异常。

@Cacheable(key = "#id")
public User findUser(int id) {
     return userDao.findUser(id);
}

@CachePut注解的作用主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和@Cacheable不同的是,它每次都会触发真实方法的调用 。简单来说就是用户更新缓存数据。但需要注意的是该注解的value和key必须与要更新的缓存相同,也就是与@Cacheable 相同。

@CachePut(key = "#id")
public User add(int id,String name,int age) {
   User user = new User(id, name, age);
   userDao.add(user);
   return user;
}
@CachePut(key = "#id")
public User update(String name,int age, int id) {
   User user = new User(id, name, age);
   userDao.update(user);
   return user;
}

@CacheEvict 将一条或多条数据从缓存中删除, 主要用于删除方法,用来从缓存中移除相应数据。

 @CacheEvict(key = "#id")
public int delete(int id) {
    return userDao.delete(id);
}

Controller层

为了展现效果,我们先定义一组简单的 RESTful API 接口进行测试。

@RestController
@RequestMapping("/user/cache")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping(value = "/list")
    public List<User> findUserList() {
        return userService.findUserList();
    }

    @GetMapping(value = "/{id}")
    public User findUser(@PathVariable("id") int id) {
        return userService.findUser(id);
    }

    @PutMapping(value = "/{id}")
    public String updateAccount(@PathVariable("id") int id, @RequestParam(value = "name", required = true) String name,
                                @RequestParam(value = "age", required = true) int age) {
        if (0 < userService.update(name, age, id)) {
            return "success";
        } else {
            return "fail";
        }
    }

    @DeleteMapping(value = "/{id}")
    public String delete(@PathVariable(value = "id") int id) {
        if (0 < userService.delete(id)) {
            return "success";
        } else {
            return "fail";
        }
    }

    @PostMapping(value = "/add")
    public String postAccount(@RequestParam(value = "id") int id, @RequestParam(value = "name") String name,
                              @RequestParam(value = "age") int age) {
        if (0 < userService.add(id, name, age)) {
            return "success";
        } else {
            return "fail";
        }
    }

}

测试

  • 多次调用查询接口
    在这里插入图片描述
    查看日志信息
    在这里插入图片描述
    由上图可知,只打印了一条日志信息,这说明缓存起了作用。
  • 调用保存接口,再调用查询接口
    在这里插入图片描述
    在这里插入图片描述
    查看日志信息
    在这里插入图片描述由上图可知,只打印了一条日志信息,这说明缓存起了作用。

扩展阅读

如果想更深入理解 Spring 的 Cache 机制,小编推荐一篇不错的文章。
Spring Cache 抽象详解

源码下载:https://github.com/chenjary/SpringBoot

猜你喜欢

转载自blog.csdn.net/Mr_Chenjie_C/article/details/84927310