SpringBoot同时集成Redis和Guava作为缓存组件--进一步分析代码
2019独角兽企业重金招聘Python工程师标准>>>
请先看
https://my.oschina.net/u/3866531/blog/1840386
CompositeCacheManager类
Composite,混合的,混成的
Spring提供CompositeCacheManager的主要目的就是为了混合使用多种缓存时进行管理。
一、实际测试--CompositeCacheManager中打断点
断点打在getCache上
GuavaDataCache源码--去掉类上的@CacheConfig(cacheManager = "guavaCacheManager")注解
package com.ding.data.cache;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import javax.annotation.PostConstruct;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;@Service//@CacheConfig(cacheManager = "guavaCacheManager")public class GuavaDataCache {private Map<Long, String> dataMap = new HashMap<Long, String>();/*** 初始化*/@PostConstructpublic void init() {dataMap.put(1L, "张三");dataMap.put(2L, "李四");dataMap.put(3L, "王五");}/*** 查询* 如果数据没有缓存,那么从dataMap里面获取,如果缓存了,* 那么从guavaDemo里面获取* 并且将缓存的数据存入到 guavaDemo里面* 其中key 为 #id+dataMap*/@Cacheable(value="guavaDemo" ,key="#id + 'dataMap'")public String query(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : query id is " + id);return dataMap.get(id);}/*** 插入 或者更新* 插入或更新数据到dataMap中* 并且缓存到 guavaDemo中* 如果存在了那么更新缓存中的值* 其中key 为 #id+dataMap*/@CachePut(value="guavaDemo" ,key="#id + 'dataMap'")public String put(Long id, String value) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : add data ,id is "+ id);dataMap.put(id, value);// data persistencereturn value;}/*** 删除* 删除dataMap里面的数据* 并且删除缓存guavaDemo中的数据* 其中key 为 #id+dataMap*/@CacheEvict(value="guavaDemo" , key="#id + 'dataMap'")public void remove(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : remove id is "+ id + " data");dataMap.remove(id);// data remove }}
RedisDataCache源码--去掉类上的@CacheConfig(cacheManager = "redisCacheManager")注解
package com.ding.data.cache;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import javax.annotation.PostConstruct;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;@Service//@CacheConfig(cacheManager = "redisCacheManager")public class RedisDataCache {private Map<Long, String> dataMap = new HashMap<Long, String>();/*** 初始化*/@PostConstructpublic void init() {dataMap.put(1L, "111");dataMap.put(2L, "222");dataMap.put(3L, "333");}/*** 查询* 如果数据没有缓存,那么从dataMap里面获取,如果缓存了,* 那么从guavaDemo里面获取* 并且将缓存的数据存入到 guavaDemo里面* 其中key 为 #id+dataMap*/@Cacheable(value="redisDemo" ,key="#id + 'dataMap'")public String query(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : query id is " + id);return dataMap.get(id);}/*** 插入 或者更新* 插入或更新数据到dataMap中* 并且缓存到 guavaDemo中* 如果存在了那么更新缓存中的值* 其中key 为 #id+dataMap*/@CachePut(value="redisDemo" ,key="#id + 'dataMap'")public String put(Long id, String value) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : add data ,id is "+ id);dataMap.put(id, value);// data persistencereturn value;}/*** 删除* 删除dataMap里面的数据* 并且删除缓存guavaDemo中的数据* 其中key 为 #id+dataMap*/@CacheEvict(value="redisDemo" , key="#id + 'dataMap'")public void remove(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : remove id is "+ id + " data");dataMap.remove(id);// data remove }}
访问http://localhost:8080/get?id=1,进入断点,看到如下
访问http://localhost:8080/getr?id=1,进入断点,看到如下
所以可见此时是通过CompositeCacheManager进行管理的,CacheConfig类中的CompositeCacheManager 起作用了
package com.ding.data.config;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.concurrent.TimeUnit;import javax.annotation.Resource;import org.springframework.boot.ApplicationArguments;import org.springframework.boot.ApplicationRunner;import org.springframework.cache.CacheManager;import org.springframework.cache.guava.GuavaCacheManager;import org.springframework.cache.support.CompositeCacheManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.StringRedisSerializer;import com.google.common.cache.CacheBuilder;import com.google.common.collect.Lists;@Configurationpublic class CacheConfig implements ApplicationRunner {@Resourceprivate List<CacheManager> cacheManagers;public void run(ApplicationArguments args) throws Exception {System.out.println("CacheManager大小为=========" + cacheManagers.size());System.out.println("=================================================");for(CacheManager c:cacheManagers){System.out.println(c.getCacheNames());}}@Bean(name = "redisCacheManager")public RedisCacheManager redisCacheManager(RedisTemplate<Object, Object> redisTemplate) {redisTemplate.setKeySerializer(new StringRedisSerializer());RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);redisCacheManager.setCacheNames(Arrays.asList("redisDemo"));redisCacheManager.setUsePrefix(true);return redisCacheManager;}@Bean(name = "guavaCacheManager")public GuavaCacheManager getGuavaCacheManager() {GuavaCacheManager guavaCacheManager = new GuavaCacheManager();guavaCacheManager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterWrite(3600, TimeUnit.SECONDS).maximumSize(1000));ArrayList<String> guavaCacheNames = Lists.newArrayList();guavaCacheNames.add("guavaDemo");guavaCacheManager.setCacheNames(guavaCacheNames);return guavaCacheManager;}@Bean(name = "cacheManager")@Primarypublic CompositeCacheManager cacheManager(RedisCacheManager redisCacheManager,GuavaCacheManager guavaCacheManager) {CompositeCacheManager cacheManager = new CompositeCacheManager(redisCacheManager, guavaCacheManager);return cacheManager;}}
二、实际测试--CompositeCacheManager中打断点
断点打在getCache上
GuavaDataCache源码--加上类上的@CacheConfig(cacheManager = "guavaCacheManager")注解
package com.ding.data.cache;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import javax.annotation.PostConstruct;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;@Service@CacheConfig(cacheManager = "guavaCacheManager")public class GuavaDataCache {private Map<Long, String> dataMap = new HashMap<Long, String>();/*** 初始化*/@PostConstructpublic void init() {dataMap.put(1L, "张三");dataMap.put(2L, "李四");dataMap.put(3L, "王五");}/*** 查询* 如果数据没有缓存,那么从dataMap里面获取,如果缓存了,* 那么从guavaDemo里面获取* 并且将缓存的数据存入到 guavaDemo里面* 其中key 为 #id+dataMap*/@Cacheable(value="guavaDemo" ,key="#id + 'dataMap'")public String query(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : query id is " + id);return dataMap.get(id);}/*** 插入 或者更新* 插入或更新数据到dataMap中* 并且缓存到 guavaDemo中* 如果存在了那么更新缓存中的值* 其中key 为 #id+dataMap*/@CachePut(value="guavaDemo" ,key="#id + 'dataMap'")public String put(Long id, String value) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : add data ,id is "+ id);dataMap.put(id, value);// data persistencereturn value;}/*** 删除* 删除dataMap里面的数据* 并且删除缓存guavaDemo中的数据* 其中key 为 #id+dataMap*/@CacheEvict(value="guavaDemo" , key="#id + 'dataMap'")public void remove(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : remove id is "+ id + " data");dataMap.remove(id);// data remove }}
RedisDataCache源码--去掉类上的@CacheConfig(cacheManager = "redisCacheManager")注解
package com.ding.data.cache;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import javax.annotation.PostConstruct;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;@Service@CacheConfig(cacheManager = "redisCacheManager")public class RedisDataCache {private Map<Long, String> dataMap = new HashMap<Long, String>();/*** 初始化*/@PostConstructpublic void init() {dataMap.put(1L, "111");dataMap.put(2L, "222");dataMap.put(3L, "333");}/*** 查询* 如果数据没有缓存,那么从dataMap里面获取,如果缓存了,* 那么从guavaDemo里面获取* 并且将缓存的数据存入到 guavaDemo里面* 其中key 为 #id+dataMap*/@Cacheable(value="redisDemo" ,key="#id + 'dataMap'")public String query(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : query id is " + id);return dataMap.get(id);}/*** 插入 或者更新* 插入或更新数据到dataMap中* 并且缓存到 guavaDemo中* 如果存在了那么更新缓存中的值* 其中key 为 #id+dataMap*/@CachePut(value="redisDemo" ,key="#id + 'dataMap'")public String put(Long id, String value) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : add data ,id is "+ id);dataMap.put(id, value);// data persistencereturn value;}/*** 删除* 删除dataMap里面的数据* 并且删除缓存guavaDemo中的数据* 其中key 为 #id+dataMap*/@CacheEvict(value="redisDemo" , key="#id + 'dataMap'")public void remove(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : remove id is "+ id + " data");dataMap.remove(id);// data remove }}
访问http://localhost:8080/get?id=1,没进入断点
访问http://localhost:8080/getr?id=1,没进入断点
所以可见,此时因为标注上了 @CacheConfig(cacheManager = "guavaCacheManager") 和 @CacheConfig(cacheManager = "redisCacheManager") ,所以直接就知道需要用哪个CacheManager了,不需要CompositeCacheManager去匹配了
直接去掉CacheConfig类中的CompositeCacheManager ,在不同的缓存上加上 @CacheConfig(cacheManager = "guavaCacheManager") 和 @CacheConfig(cacheManager = "redisCacheManager"),是否可以?——测试一下
此时的CacheConfig类代码
package com.ding.data.config;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.concurrent.TimeUnit;import javax.annotation.Resource;import org.springframework.boot.ApplicationArguments;import org.springframework.boot.ApplicationRunner;import org.springframework.cache.CacheManager;import org.springframework.cache.guava.GuavaCacheManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.StringRedisSerializer;import com.google.common.cache.CacheBuilder;import com.google.common.collect.Lists;@Configurationpublic class CacheConfig implements ApplicationRunner {@Resourceprivate List<CacheManager> cacheManagers;public void run(ApplicationArguments args) throws Exception {System.out.println("CacheManager大小为=========" + cacheManagers.size());System.out.println("=================================================");for(CacheManager c:cacheManagers){System.out.println(c.getCacheNames());}}@Bean(name = "redisCacheManager")public RedisCacheManager redisCacheManager(RedisTemplate<Object, Object> redisTemplate) {redisTemplate.setKeySerializer(new StringRedisSerializer());RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);redisCacheManager.setCacheNames(Arrays.asList("redisDemo"));redisCacheManager.setUsePrefix(true);return redisCacheManager;}@Bean(name = "guavaCacheManager")public GuavaCacheManager getGuavaCacheManager() {GuavaCacheManager guavaCacheManager = new GuavaCacheManager();guavaCacheManager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterWrite(3600, TimeUnit.SECONDS).maximumSize(1000));ArrayList<String> guavaCacheNames = Lists.newArrayList();guavaCacheNames.add("guavaDemo");guavaCacheManager.setCacheNames(guavaCacheNames);return guavaCacheManager;}// @Bean(name = "cacheManager")// @Primary// public CompositeCacheManager cacheManager(// RedisCacheManager redisCacheManager,// GuavaCacheManager guavaCacheManager) {// CompositeCacheManager cacheManager = new CompositeCacheManager(// redisCacheManager, guavaCacheManager);// return cacheManager;// }}
结果启动时就报错了
java.lang.IllegalStateException: No CacheResolver specified, and no unique bean of type CacheManager found. Mark one as primary (or give it the name 'cacheManager') or declare a specific CacheManager to use, that serves as the default one.
at org.springframework.cache.interceptor.CacheAspectSupport.afterSingletonsInstantiated(CacheAspectSupport.java:186) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:792) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at com.ding.data.App.main(App.java:33) [classes/:na]
上面报错是因为Spring Context 中存在多个实现了 CacheManager.class 的 Bean,需要使用 @Primary 注解指定优先选择的 CacheManager
那么指定 GuavaCacheManager 为 @Primary,此时的CacheConfig类代码
package com.ding.data.config;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.concurrent.TimeUnit;import javax.annotation.Resource;import org.springframework.boot.ApplicationArguments;import org.springframework.boot.ApplicationRunner;import org.springframework.cache.CacheManager;import org.springframework.cache.guava.GuavaCacheManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.StringRedisSerializer;import com.google.common.cache.CacheBuilder;import com.google.common.collect.Lists;@Configurationpublic class CacheConfig implements ApplicationRunner {@Resourceprivate List<CacheManager> cacheManagers;public void run(ApplicationArguments args) throws Exception {System.out.println("CacheManager大小为=========" + cacheManagers.size());System.out.println("=================================================");for(CacheManager c:cacheManagers){System.out.println(c.getCacheNames());}}@Bean(name = "redisCacheManager")public RedisCacheManager redisCacheManager(RedisTemplate<Object, Object> redisTemplate) {redisTemplate.setKeySerializer(new StringRedisSerializer());RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);redisCacheManager.setCacheNames(Arrays.asList("redisDemo"));redisCacheManager.setUsePrefix(true);return redisCacheManager;}@Bean(name = "guavaCacheManager")@Primarypublic GuavaCacheManager getGuavaCacheManager() {GuavaCacheManager guavaCacheManager = new GuavaCacheManager();guavaCacheManager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterWrite(3600, TimeUnit.SECONDS).maximumSize(1000));ArrayList<String> guavaCacheNames = Lists.newArrayList();guavaCacheNames.add("guavaDemo");guavaCacheManager.setCacheNames(guavaCacheNames);return guavaCacheManager;}// @Bean(name = "cacheManager")// @Primary// public CompositeCacheManager cacheManager(// RedisCacheManager redisCacheManager,// GuavaCacheManager guavaCacheManager) {// CompositeCacheManager cacheManager = new CompositeCacheManager(// redisCacheManager, guavaCacheManager);// return cacheManager;// }}
正常启动,刚才的报错消失
测试,一切正常
所以不需要使用CompositeCacheManager类,在使用缓存的地方通过 @CacheConfig 指定CacheManager,就可以混合使用多种缓存组件了。同时,要记得在配置类中指定一个 @Primary 缓存
转载于:https://my.oschina.net/u/3866531/blog/1840530
SpringBoot同时集成Redis和Guava作为缓存组件--进一步分析代码相关推荐
- SpringBoot 05 集成redis实现对象序列化缓存
1.为什么用Spring Data Spring Data 的目标是为数据访问提供一个基于Spring的普遍常用的编程模型,同时仍然保留底层数据存储的特殊特性, 它让使用数据访问技术.关系和非关系数据 ...
- 【JAVA秘籍功法篇-SpringBoot】SpringBoot如何集成Redis?
SpringBoot如何集成redis 大家好,我是王老狮,一个有思想有内涵的架构狮.Redis作为分布式缓存,在我们的项目中经常会用到,今天我们看下SpringBoot如何集成redis. POM中 ...
- Springboot:整合redis对接口数据进行缓存
文章目录 Springboot:整合redis对接口数据进行缓存 一.注解及其属性介绍 @Cacheable @CacheEvict @CachePut @CacheConfig 二.代码实现 1.创 ...
- SpringBoot中集成Redis实现对redis中数据的解析和存储
场景 SpringBoot中操作spring redis的工具类: SpringBoot中操作spring redis的工具类_霸道流氓气质的博客-CSDN博客 上面讲的操作redis的工具类,但是对 ...
- SpringBoot2.0 基础案例(08):集成Redis数据库,实现缓存管理
一.Redis简介 Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, Elastic ...
- go语言高性能缓存组件ccache分析
1. 背景 在撸代码时,利用局部性原理对数据做缓存是一种常用的性能优化手段. 要做缓存,离不开的就是缓存组件.ccache就是一个很优秀的lru缓存组件,其做了很多很巧妙的优化策略来降低锁冲突,实现高 ...
- SpringBoot简单集成Redis,实现简单查询
1引入redis的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId& ...
- Redis第三话 – Springboot集成Redis以及常用API和客户端介绍
本文主要记录在Springboot中集成Redis的使用. 1. springboot集成redis 1.1 maven配置 基于springboot 版本2.5.6,parent包就不贴了. < ...
- spring boot 缓存_Spring Boot 集成 Redis 实现数据缓存
Spring Boot 集成 Redis 实现数据缓存,只要添加一些注解方法,就可以动态的去操作缓存了,减少代码的操作. 在这个例子中我使用的是 Redis,其实缓存类型还有很多,例如 Ecache. ...
最新文章
- python3最新版本-Python3第三方组件最新版本追踪实现
- KVM中virtio、vhost 和vhost-user比较(十一)
- java、intellij idea、groovy
- 实例3:按部门统计工资人数
- 【渝粤题库】陕西师范大学202881 电子商务概论
- 深度残差网络的无人机多目标识别
- java规定日期格式输出_Java格式化输出日期百分比时间等
- 事件Event:带你体验鸿蒙轻内核中一对多、多对多任务同步
- 一加、OPPO官宣合并,“父子团圆”能否拯救一加?
- 软件著作权算法软件设计说明书_软件详细设计说明书例子.pdf
- Grouping BP has not been assigned to any customer accounts groupMessage no. FSBP_ECC004
- 【数学模拟卷总结】2022李林四套卷数学二第二套
- 在 HTML 中使用 ARIA 的规则
- shell foreach
- php 图片获得大小,PHP获取一张图片的宽度和高度大小 并裁切图片
- html app下载页功能开发
- selenium找到页面元素click没反应
- 关于Windows在ping虚拟机时出现请求超时的解决问题
- 海康嵌入式软件面试经验(已拿offer)
- The CompactFlash Association宣布推出CFexpress(R)2.0规范
热门文章
- Android开发工具新接触
- 重置密码遇到ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using passwor:yes)问题
- python 字符串反转
- 基于python的移动物体检测_感兴趣区域的移动物体检测,框出移动物体的轮廓 (固定摄像头, opencv-python)...
- 剑指offer java 博客_Java--剑指offer(10)
- access设计视图打不开_定制橱柜衣柜怎么测量才能避免出错?(设计师必看)
- 微信小程序长按保存图片
- linux shell 学习小结
- mysql+数据库连接标识_新人必看!连接到MySQL数据库的两种方法
- 顺序表应用3:元素位置互换之移位算法