我是靠谱客的博主 伶俐刺猬,最近开发中收集的这篇文章主要介绍springboot整个缓存_SpringBoot同时集成Redis和Guava作为缓存组件--进一步分析代码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

请先看

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 dataMap = new HashMap();

/**

* 初始化

*/

@PostConstruct

public 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 persistence

return 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 dataMap = new HashMap();

/**

* 初始化

*/

@PostConstruct

public 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 persistence

return 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

}

}

所以可见此时是通过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;

@Configuration

public class CacheConfig implements ApplicationRunner {

@Resource

private List 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 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 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中打断点

断点打在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 dataMap = new HashMap();

/**

* 初始化

*/

@PostConstruct

public 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 persistence

return 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 dataMap = new HashMap();

/**

* 初始化

*/

@PostConstruct

public 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 persistence

return 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

}

}

所以可见,此时因为标注上了@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;

@Configuration

public class CacheConfig implements ApplicationRunner {

@Resource

private List 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 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 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;

@Configuration

public class CacheConfig implements ApplicationRunner {

@Resource

private List 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 redisTemplate) {

redisTemplate.setKeySerializer(new StringRedisSerializer());

RedisCacheManager redisCacheManager = new RedisCacheManager(

redisTemplate);

redisCacheManager.setCacheNames(Arrays.asList("redisDemo"));

redisCacheManager.setUsePrefix(true);

return redisCacheManager;

}

@Bean(name = "guavaCacheManager")

@Primary

public GuavaCacheManager getGuavaCacheManager() {

GuavaCacheManager guavaCacheManager = new GuavaCacheManager();

guavaCacheManager.setCacheBuilder(CacheBuilder.newBuilder()

.expireAfterWrite(3600, TimeUnit.SECONDS).maximumSize(1000));

ArrayList 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缓存

最后

以上就是伶俐刺猬为你收集整理的springboot整个缓存_SpringBoot同时集成Redis和Guava作为缓存组件--进一步分析代码的全部内容,希望文章能够帮你解决springboot整个缓存_SpringBoot同时集成Redis和Guava作为缓存组件--进一步分析代码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)

评论列表共有 0 条评论

立即
投稿
返回
顶部