springboot整合redis-sentinel支持Cache注解

时间:2022-09-18 13:39:22

一、前提

已经存在一个redis-sentinel集群,两个哨兵分别如下:

/home/redis-sentinel-cluster/sentinel-1.conf
springboot整合redis-sentinel支持Cache注解
port 26379

dir "/data"
sentinel monitor mymaster 172.16.1.11 16379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 5000
sentinel parallel-syncs mymaster 1
springboot整合redis-sentinel支持Cache注解
/home/redis-sentinel-cluster/sentinel-2.conf
springboot整合redis-sentinel支持Cache注解
port 26380

dir "/data"
sentinel monitor mymaster 172.16.1.11 16379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 5000
sentinel parallel-syncs mymaster 1
springboot整合redis-sentinel支持Cache注解

二、新建maven工程:redis-sentinel-demo    最终完整工程如下:

springboot整合redis-sentinel支持Cache注解

pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<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.redis.sentinel.demo</groupId>
<artifactId>redis-sentinel-demo</artifactId>
<version>1.0-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--以下是spring整合redis的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies> </project>

1、application.yml

server:
port: 8083
context-path: / spring:
redis:
sentinel:
master: mymaster
nodes: 172.16.1.11:26379,172.16.1.11:26380
pool:
max-active: 8
max-idle: 8
max-wait: -1
min-idle: 0
database: 0

2、新建redis的工具类RedisUtil

package com.redis.sentinel.demo.util;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; /**
* @author Administrator
* @date 2019/03/19
*/
public class RedisUtil { private RedisTemplate<String, Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
//=============================common============================
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key,long time){
try {
if(time>0){
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key){
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
} /**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key){
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key){
if(key!=null&&key.length>0){
if(key.length==1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
} //============================String=============================
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public Object get(String key){
return key==null?null:redisTemplate.opsForValue().get(key);
} /**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key,Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} } /**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key,Object value,long time){
try {
if(time>0){
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}else{
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 递增
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta){
if(delta<0){
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
} /**
* 递减
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta){
if(delta<0){
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
} //================================Hash=================================
/**
* HashGet
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object hget(String key,String item){
return redisTemplate.opsForHash().get(key, item);
} /**
* 获取hashKey对应的所有值
* @param key 键
* @return 对应的多个值
*/
public Map<Object,Object> hmget(String key){
return redisTemplate.opsForHash().entries(key);
} /**
* HashSet
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String,Object> map){
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* HashSet 并设置时间
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String,Object> map, long time){
try {
redisTemplate.opsForHash().putAll(key, map);
if(time>0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key,String item,Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key,String item,Object value,long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if(time>0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 删除hash表中的值
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item){
redisTemplate.opsForHash().delete(key,item);
} /**
* 判断hash表中是否有该项的值
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item){
return redisTemplate.opsForHash().hasKey(key, item);
} /**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item,double by){
return redisTemplate.opsForHash().increment(key, item, by);
} /**
* hash递减
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item,double by){
return redisTemplate.opsForHash().increment(key, item,-by);
} //============================set=============================
/**
* 根据key获取Set中的所有值
* @param key 键
* @return
*/
public Set<Object> sGet(String key){
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 根据value从一个set中查询,是否存在
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key,Object value){
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 将数据放入set缓存
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object...values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
} /**
* 将set数据放入缓存
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key,long time,Object...values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if(time>0) expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
} /**
* 获取set缓存的长度
* @param key 键
* @return
*/
public long sGetSetSize(String key){
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
} /**
* 移除值为value的
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object ...values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============================list================================= /**
* 获取list缓存的内容
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end){
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 获取list缓存的长度
* @param key 键
* @return
*/
public long lGetListSize(String key){
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
} /**
* 通过索引 获取list中的值
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public Object lGetIndex(String key,long index){
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 根据索引修改list中的某条数据
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index,Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 用于移除键中指定的元素。接受3个参数,分别是缓存的键名,计数事件,要移除的值。计数事件可以传入的有三个值,分别是-1、0、1。
-1代表从存储容器的最右边开始,删除一个与要移除的值匹配的数据;0代表删除所有与传入值匹配的数据;1代表从存储容器的最左边开始,删除一个与要移除的值匹配的数据。
* @param key 键
* @param count
* @param value 值
* @return 移除的个数
*/
public void lRemove(String key,long count,Object value) {
try {
redisTemplate.opsForList().remove(key, count, value);
} catch (Exception e) {
e.printStackTrace();
}
}
}

3、新建RedisConfig(主要是设置实例化redisTemplate,并设置序列化,同时实例化RedisUtil)

package com.redis.sentinel.demo.config;

import com.redis.sentinel.demo.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; /**
* @author Administrator
* @date 2019/03/19
*/
@Configuration
@EnableCaching //开启缓存,还要继承于CachingConfigurerSupport,主要是为了注解@Cacheable、@CacheEvict、@CachePut等的使用
public class RedisConfig extends CachingConfigurerSupport {
/**
* 注入 RedisConnectionFactory
*/
@Autowired
RedisConnectionFactory redisConnectionFactory; /**
* 实例化 RedisTemplate 对象
*
* @return
*/
@Bean
public RedisTemplate<String, Object> functionDomainRedisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
return redisTemplate;
} /**
* 设置数据存入 redis 的序列化方式
*
* @param redisTemplate
* @param factory
*/
private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//只有设置jdk序列化,才能新类对象比如User进行存储
redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setConnectionFactory(factory);
} /**
* 实例化RedisUtil
* @param redisTemplate
* @return
*/
@Bean
public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
RedisUtil redisUtil = new RedisUtil();
redisUtil.setRedisTemplate(redisTemplate);
return redisUtil;
}
}

4、创建RedisTestController

package com.redis.sentinel.demo.controller;

import com.redis.sentinel.demo.model.User;
import com.redis.sentinel.demo.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set; /**
* @author Administrator
* @date 2019/03/19
*/
@RestController
@RequestMapping("/redis-sentinel")
public class RedisTestController {
@Autowired
private RedisUtil redisUtil;
@RequestMapping(value = "/test",method = RequestMethod.POST)
public void postTest(){
testCommon();
testHash();
testSet();
testList();
} private void testCommon(){
System.out.println("================================测试普通缓存==================");
System.out.println("普通缓存,存入 key01 值为value01 到期时间为5秒");
redisUtil.set("key01","value01",5);
System.out.println("从redis获取key01的值:"+redisUtil.get("key01"));
System.out.println("到期时间为:"+redisUtil.getExpire("key01"));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("6秒后从redis获取key01的值:"+redisUtil.get("key01"));
System.out.println("key01是否存在:"+redisUtil.hasKey("key01"));
} private void testHash(){
System.out.println("================================测试Hash缓存==================");
System.out.println("hash缓存,存入 key03 值为{\"name\":\"zhangsan\",\"sex\":\"man\"}");
Map<String,Object> map = new HashMap<>();
map.put("name","zhangsan");
map.put("sex","man");
redisUtil.hmset("key03",map);
System.out.println("key03:"+redisUtil.hget("key03","name")+" "+redisUtil.hget("key03","sex"));
redisUtil.del("key03");
} private void testSet(){
System.out.println("================================测试Set缓存==================");
System.out.println("Set缓存,将两个User放入缓存key04");
redisUtil.sSet("key04",new User("name1","man"),new User("name2","femal"));
Set<Object> users = redisUtil.sGet("key04");
for(Object o:users){
User user = (User)o;
System.out.println(o.toString());
}
System.out.println("获取Set key04的长度:"+redisUtil.sGetSetSize("key04"));
System.out.println("删除key04");
redisUtil.del("key04");
System.out.println("获取Set key04的长度:"+redisUtil.sGetSetSize("key04")); } private void testList(){
System.out.println("================================测试List缓存==================");
System.out.println("List缓存key05");
redisUtil.lSet("key05", Arrays.asList("aa","bb","cc","dd","ee","ff","gg"));
System.out.println("List缓存key06");
redisUtil.lSet("key06","11");
redisUtil.lSet("key06","22");
redisUtil.lSet("key06","33");
redisUtil.lSet("key06","44");
redisUtil.lSet("key06","55");
redisUtil.lSet("key06","66");
redisUtil.lSet("key06","77");
System.out.println("以上两种方式的缓存是有区别的,注意看下面的长度");
System.out.println("输出key05的长度:"+redisUtil.lGetListSize("key05"));
List<Object> list = redisUtil.lGet("key05",0,redisUtil.lGetListSize("key05"));
System.out.println("输出key05的所有元素");
for(Object str:list){
System.out.println(str);
}
System.out.println("输出key06的长度:"+redisUtil.lGetListSize("key06"));
List<Object> list1 = redisUtil.lGet("key06",0,redisUtil.lGetListSize("key06"));
System.out.println("输出key06的所有元素");
for(Object str:list1){
System.out.println(str);
} System.out.println("删除key06的的55");
redisUtil.lRemove("key06",1,"55");
List<Object> list2 = redisUtil.lGet("key06",0,redisUtil.lGetListSize("key06"));
System.out.println("输出key06的长度:"+redisUtil.lGetListSize("key06"));
System.out.println("输出key06的所有元素");
for(Object str:list2){
System.out.println(str);
} redisUtil.del("key06");
redisUtil.del("key05"); }
}

5、创建springboot启动类

package com.redis.sentinel.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; /**
* @author Administrator
* @date 2019/03/19
*/
@SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}

6、启动程序并用postman进行测试

springboot整合redis-sentinel支持Cache注解

================================测试普通缓存==================
普通缓存,存入 key01 值为value01 到期时间为5秒
从redis获取key01的值:value01
到期时间为:
6秒后从redis获取key01的值:null
key01是否存在:false
================================测试Hash缓存==================
hash缓存,存入 key03 值为{"name":"zhangsan","sex":"man"}
key03:zhangsan man
================================测试Set缓存==================
Set缓存,将两个User放入缓存key04
User{name='name2', sex='femal'}
User{name='name1', sex='man'}
获取Set key04的长度:
删除key04
获取Set key04的长度:
================================测试List缓存==================
List缓存key05
List缓存key06
以上两种方式的缓存是有区别的,注意看下面的长度
输出key05的长度:
输出key05的所有元素
[aa, bb, cc, dd, ee, ff, gg]
输出key06的长度:
输出key06的所有元素 删除key06的的55
输出key06的长度:
输出key06的所有元素

三、使用Cache注解

1、@Cacheable

@Cacheable是用来声明方法是可缓存的。将结果存储到缓存中以便后续使用相同参数调用时不需执行实际的方法。直接从缓存中取值。最简单的格式需要制定缓存名称。主要用于查询。

 参数  解释  示例
 value  缓存的名称,必须指定至少一个  
@Cacheable(value=”users”)
@Cacheable(value={”users1”,”users2”}
 key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
@Cacheable(value = "users", key = "#name")
@Cacheable(value = "users", key = "#p0")
 condition  缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
@Cacheable(value = "users",key = "#p0", condition = "#p0 != null")

2、@CachePut

如果缓存需要更新,且不干扰方法的执行,可以使用注解@CachePut。@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

 参数  解释  示例
 value  缓存的名称,必须指定至少一个  
@CachePut(value=”users”)
@CachePut(value={”users1”,”users2”}
 key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
@CachePut(value = "users", key = "#name")
@CachePut(value = "users", key = "#p0")
 condition  缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
@CachePut(value = "users",key = "#p0", condition = "#p0 != null")

3、@CacheEvict

@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空

 参数  解释  示例
 value  缓存的名称,必须指定至少一个  
@CacheEvict(value=”users”)
 key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
@CacheEvict(value = "users", key = "#name")
@CacheEvict(value = "users", key = "#p0")
 condition  缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
@CacheEvict(value = "users",key = "#p0", condition = "#p0 != null")
 allEntries 缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
@CacheEvict(value = "users",allEntries=true)
 beforeInvocation 缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存
@CacheEvict(value = "users",beforeInvocation=true)

4、@Caching

有时候我们可能组合多个Cache注解使用

以上四个个注解的示例程序如下:

在上面的程中新建RedisCachableController

package com.redis.sentinel.demo.controller;

import com.redis.sentinel.demo.model.User;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import java.util.HashMap;
import java.util.Map; /**
* @author Administrator
* @date 2019/03/21
*/
@RestController
@RequestMapping("/redis-sentinel-cache")
public class RedisCachableController { private Map<String, Object> userList = new HashMap<>();
/**
* 按key为user.name进行缓存
* @param user
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
@CachePut(value = "users", key = "#user.name")
public User addUser(@RequestBody User user) {
userList.put(user.getName(), user);
return user;
} /**
* 组合多个Cache注解使用,按user.name和user.sex两个维度进行缓存
* @param user
* @return
*/
@RequestMapping(value = "/add2", method = RequestMethod.POST)
@Caching(put = {
@CachePut(value = "users", key = "#user.name"),
@CachePut(value = "users", key = "#user.sex")
})
public User addUser2(@RequestBody User user) {
userList.put(user.getName(), user);
return user;
} /**
* 先从缓存查数据,如果缓存没有,则到userList里面去拿。
* @param name
* @return
*/
@RequestMapping(value = "/query", method = RequestMethod.GET)
@Cacheable(value = "users", key = "#name", condition = "#name != null")
public User queryUserByName(@RequestParam(value = "name") String name) {
System.out.println("如果缓存没有,从map里面获取");
User user = (User) userList.get(name);
return user;
} /**
* 删除数据,从缓存中删除
* @param name
*/
@RequestMapping(value = "/del", method = RequestMethod.PUT)
@CacheEvict(value = "users", key = "#name", condition = "#name != null")
public void deleteUserByName(@RequestParam(value = "name") String name) { }
}

启动程序,用postman进行测试

1)执行add方法,将信息存入缓存

springboot整合redis-sentinel支持Cache注解

2)执行query方法,查看console

springboot整合redis-sentinel支持Cache注解

springboot整合redis-sentinel支持Cache注解

3)执行del方法,删除缓存

springboot整合redis-sentinel支持Cache注解

4)执行query方法,查看console

springboot整合redis-sentinel支持Cache注解

 5、@CacheConfig

所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了, 所以,有了@CacheConfig这个配置,作用在类上面,可以将上面的Controller类进行改造

在上面的程中新建RedisCachableController1

package com.redis.sentinel.demo.controller;

import com.redis.sentinel.demo.model.User;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import java.util.HashMap;
import java.util.Map; /**
* @author Administrator
* @date 2019/03/21
*/
@RestController
@RequestMapping("/redis-sentinel-cache2")
@CacheConfig(cacheNames = "users")
public class RedisCachableController1 { private Map<String, Object> userList = new HashMap<>();
/**
* 按key为user.name进行缓存
* @param user
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
@CachePut(key = "#user.name")
public User addUser(@RequestBody User user) {
userList.put(user.getName(), user);
return user;
} /**
* 组合多个Cache注解使用,按user.name和user.sex两个维度进行缓存
* @param user
* @return
*/
@RequestMapping(value = "/add2", method = RequestMethod.POST)
@Caching(put = {
@CachePut( key = "#user.name"),
@CachePut( key = "#user.sex")
})
public User addUser2(@RequestBody User user) {
userList.put(user.getName(), user);
return user;
} /**
* 先从缓存查数据,如果缓存没有,则到userList里面去拿。
* @param name
* @return
*/
@RequestMapping(value = "/query", method = RequestMethod.GET)
@Cacheable( key = "#p0", condition = "#p0 != null")
public User queryUserByName(@RequestParam(value = "name") String name) {
System.out.println("如果缓存没有,从map里面获取");
User user = (User) userList.get(name);
return user;
} /**
* 删除数据,从缓存中删除
* @param name
*/
@RequestMapping(value = "/del", method = RequestMethod.PUT)
@CacheEvict(key = "#name", condition = "#name != null")
public void deleteUserByName(@RequestParam(value = "name") String name) { }
}

SpEL表达式

Spring Cache提供了一些供我们使用的SpEL上下文数据,下表直接摘自Spring官方文档:

名称 位置 描述 示例
methodName root对象 当前被调用的方法名 root.methodName
method root对象 当前被调用的方法 root.method.name
target root对象 当前被调用的目标对象 root.target
targetClass root对象 当前被调用的目标对象类 root.targetClass
args root对象 当前被调用的方法的参数列表 root.args[0]
caches root对象 当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”, “cache2”})),则有两个cache root.caches[0].name
argument name 执行上下文 当前被调用的方法的参数,如findById(Long id),我们可以通过#id拿到参数 user.id
result 执行上下文 方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,’cache evict’的beforeInvocation=false) result

springboot整合redis-sentinel支持Cache注解的更多相关文章

  1. springboot整合redis&lpar;注解形式&rpar;

    springboot整合redis(注解形式) 准备工作 springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式去整合,即采用spring ...

  2. springboot整合redis——redisTemplate的使用

    一.概述 相关redis的概述,参见Nosql章节 redisTemplate的介绍,参考:http://blog.csdn.net/ruby_one/article/details/79141940 ...

  3. Springboot整合Redis入门完整篇,零基础入门教学教程

    记录一次简易集成Redis缓存 自定义Redisconfig配置 自定义序列化操作 加深印像 整合前提工具环境准备: 1.redis官网 https://redis.io/download 下载安装r ...

  4. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

  5. 九、springboot整合redis二之缓冲配置

    1.创建Cache配置类 @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSu ...

  6. springBoot整合redis&lpar;作缓存&rpar;

    springBoot整合Redis 1,配置Redis配置类 package org.redislearn.configuration; import java.lang.reflect.Method ...

  7. SpringBoot整合Redis及Redis工具类撰写

            SpringBoot整合Redis的博客很多,但是很多都不是我想要的结果.因为我只需要整合完成后,可以操作Redis就可以了,并不需要配合缓存相关的注解使用(如@Cacheable). ...

  8. SpringBoot系列十:SpringBoot整合Redis

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合 Redis 2.背景 Redis 的数据库的整合在 java 里面提供的官方工具包:jed ...

  9. SpringBoot整合redis哨兵主从服务

    前提环境: 主从配置 http://www.cnblogs.com/zwcry/p/9046207.html 哨兵配置 https://www.cnblogs.com/zwcry/p/9134721. ...

  10. SpringBoot整合Redis使用Restful风格实现CRUD功能

    前言 本篇文章主要介绍的是SpringBoot整合Redis,使用Restful风格实现的CRUD功能. Redis 介绍 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-valu ...

随机推荐

  1. CAS学习笔记(二)—— cas server端的login-webflow详细流程

    一.配置文件介绍 关于spring的配置信息只需放入WEB-INF/spring-configuration目录即可,cas启动时会自动加载.这个目录下的spring配置文件几乎不需要改动. 在web ...

  2. virtio 半虚拟化驱动

    半虚拟化驱动 5.1.1 virtio概述 KVM是必须使用硬件虚拟化辅助技术(如Intel VT-x.AMD-V)的hypervisor,在CPU运行效率方面有硬件支持,其效率是比较高的:在有Int ...

  3. Cannot install NodeJs&colon; &sol;usr&sol;bin&sol;env&colon; node&colon; No such file or directory

    安装doxmate时,doxmate地址是:https://github.com/JacksonTian/doxmatenpm install doxmate -g 安装完后把错误:Cannot in ...

  4. Linux下PHP&plus;MySQL&plus;CoreSeek中文检索引擎配置

    说明: 操作系统:CentOS 5.X 服务器IP地址:192.168.21.127 Web环境:Nginx+PHP+MySQL 站点根目录:/usr/local/nginx/html 目的:安装co ...

  5. 单机Hadoop搭建

    通过一段时间的学习,我在我的centos上安装了单机hadoop,如果这对你有帮助,就进来探讨学习一下 Hadoop伪分布式配置 Hadoop 可以在单节点上以伪分布式的方式运行,Hadoop 进程以 ...

  6. jenkins的sbt插件安装

    在jenkins服务器手动安装sbt curl https://bintray.com/sbt/rpm/rpm > bintray-sbt-rpm.repo mv bintray-sbt-rpm ...

  7. Mysql AVG&lpar;&rpar; 值 返回NULL而非空结果集

    [1]select 查询返回一行NULL 先来模拟复现一下遇到的问题. (1)源数据表grades,学生成绩表 (2)查询SQL语句 查询‘080601’班的各门课平均成绩 SELECT sClass ...

  8. 微信小程序与Vue js数据渲染对比

    //小程序 Page({ data: { items: [] }, onLoad: function(options) { this.setData({ items: [1,2,3] }) } }) ...

  9. bootstrap datepicker含有hasDatepicker无法弹出

    bootstrap datepicker 初始化时,会给控件添加hasDatepicker类 ,如果此时调用 $singleDay.datepicker(initDayOpts);无法弹出时间控件 需 ...

  10. NLP--自然语言处理与机器学习会议

    http://blog.csdn.net/ice110956/article/details/17090061 整理至11月中旬在重庆参加的自然语言处理与机器学习会议,第一讲为自然语言处理. 由基本理 ...