SpringBoot同时集成Guava和Redis作为缓存

参考网页

http://tramp.cincout.cn/2017/10/31/spring-boot-2017-10-31-spring-boot-multi-cache-manager/

为什么要混用缓存(本地缓存和分布式缓存)?

这个要看项目实际需要。一种场景就是有部分数据只是各个服务实例自己需要,所以用本地缓存(如Guava、EhCache)即可,这样也方便简洁;而同时有的数据需要各个服务实例共享,这种数据就适合存储于分布式缓存中(如Redis)。

代码结构图

要点1-POM--标黄色部分在SpringBoot中引入了Redis和Guava

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.ding.data</groupId>

<artifactId>serverlCacheCase</artifactId>

<version>0.0.1-SNAPSHOT</version>


<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<boot.version>1.3.5.RELEASE</boot.version>

</properties>


<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

<version>${boot.version}</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<version>${boot.version}</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-cache</artifactId>

<version>${boot.version}</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-redis</artifactId>

<version>${boot.version}</version>

</dependency>

<dependency> 

<groupId>com.google.guava</groupId> 

<artifactId>guava</artifactId> 

<version>19.0</version> 

</dependency>

</dependencies>

</project>

要点2-application.yml

   

 spring:

      #cache:

        #缓存名称

        #cache-names: guavaDemo

        #缓存最大数量500条, 缓存失效时间 6个小时

        #guava.spec: maximumSize=500,expireAfterWrite=360m

      # REDIS (RedisProperties)  

      redis :

        host : localhost # server host  

        port : 6379 # connection port  

        password : 123

        pool.max-idle : 8 # pool settings ...  

        pool.min-idle : 1

        pool.max-active : 8  

        pool.max-wait : -1  

★要点3--配置类

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

}

}

要点4--guava缓存

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>();


/**

 * 初始化

 */

@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  

}


}

要点5--redis缓存

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>();


/**

 * 初始化

 */

@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  

}


}

要点6--调用

package com.ding.data;


import java.text.SimpleDateFormat;

import java.util.Date;


import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cache.annotation.EnableCaching;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;


import com.ding.data.cache.GuavaDataCache;

import com.ding.data.cache.RedisDataCache;


/**

 * 是Spring Boot项目的核心注解,主要是开启自动配置

 */

@SpringBootApplication

// same as @Configuration @EnableAutoConfiguration @ComponentScan

@RestController

// 开启缓存

@EnableCaching

public class App {


@Autowired

private GuavaDataCache dataCache;


@Autowired

private RedisDataCache rdataCache;


public static void main(String[] args) {

SpringApplication.run(App.class, args);

}


@RequestMapping("/put")

public String put(Long id, String value) {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

return sdf.format(new Date()) + " : value is "

+ dataCache.put(id, value);

}


@RequestMapping("/get")

public String query(Long id) {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

return sdf.format(new Date()) + " : value is " + dataCache.query(id);

}


@RequestMapping("/remove")

public String remove(Long id) {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

dataCache.remove(id);

return sdf.format(new Date()) + " : success ";

}


@RequestMapping("/putr")

public String putr(Long id, String value) {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

return sdf.format(new Date()) + " : value is "

+ rdataCache.put(id, value);

}


@RequestMapping("/getr")

public String queryr(Long id) {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

return sdf.format(new Date()) + " : value is " + rdataCache.query(id);

}


@RequestMapping("/remover")

public String remover(Long id) {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

rdataCache.remove(id);

return sdf.format(new Date()) + " : success ";

}


}

测试1--redis中是否有写入--有的

RedisCache访问

访问

http://localhost:8080/getr?id=1

查看Redis服务器中,如下

可见

/getr?id=1

这个链接返回时将数据写入了Redis服务器中。

RedisCache写入

访问

http://localhost:8080/putr?id=1&value=999999

然后查看Redis服务器,如下图

测试2--guava缓存的访问

访问

http://localhost:8080/get?id=1

然后调用

http://localhost:8080/put?id=1&value=777777

查看Redis中的值,并未发生任何改变。说明redis缓存和guava缓存互不干扰,都按照设想的进行了正确的访问。为什么这么说?因为之前试过别的配置,结果发现缓存发生了混乱,而现在正常,说明现在的配置类文件和相关的配置信息都写正确了。

★要点3讲解

项目启动过程中打印

项目启动过程中打印如下。ApplicationRunner接口的具体用法可以自行百度。实现ApplicationRunner接口并不是必须的,这里就是为了启动时打印展示CacheManager。

从图中可以看到被 @Bean 注解的三个CachaManager都加进了 cacheManagers 中。

CompositeCacheManager

Spring Cache在 CacheManager 之下可以采用缓存名称(cacheNames 属性)来对缓存进行区分。Spring Cache 提供了CompositeCacheManager 来对所有的 CacheManager 进行代理。根据指定的cacheName 去遍历所有的 CacheManager,查找对应的缓存。

转载于:https://my.oschina.net/u/3866531/blog/1840386

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值