springboot cache集成redis

spring boot cache 集成redis

spring cache

为了统一各种缓存的接入流程,spring 设计了统一spring cache缓存模块,将所有操作进行了抽象,主要为Cache和CacheManager。
在这里插入图片描述
看一下spring 默认有以下几种实现。
在这里插入图片描述

CacheManager结构如下:

在这里插入图片描述
CacheManager的默认以下实现。
在这里插入图片描述

spring cache的默认实现为ConcurrentMapCache,下面我们修改默认实现,将缓存替换为redis,并详细演示了@Cacheable的使用。

首先看下该注解结构:
在这里插入图片描述
value、cacheNames :用来指定缓存组件的名字
key :缓存数据时使用的 key。默认是使用方法参数的值。可以使用 spEL 表达式来编写。
keyGenerator :key 的生成器。 key 和 keyGenerator 二选一使用
cacheManager :可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。
condition :可以用来指定符合条件的情况下才缓存
unless :否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。
sync :是否使用异步模式。

在采用默认配置的情况下,只需要引入redis的依赖即可,非常简单(创建spring boot项目此处不做介绍)。
在pom文件中添加以下redis依赖

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>

在配置文件中添加redis的地址等信息,根据自己的需求即可。

spring.redis.host=192.168.1.11
spring.redis.password=123456
spring.redis.port=6379

到此为止我们就把cache的默认实现换成redis了,下面我们写代码来验证以下。

本文的项目结构如下
在这里插入图片描述
看一下service的代码

@Service
public class CacheService {

    @Cacheable("demo01")
    public int demo01(int i){
        System.out.println("=========》模拟查询数据库获取数据");
        return  i*i;
    }
}

此处我们测试注解@Cacheable,value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,此处我们取名demo01。
编写好service后我们在编写一个controller,

@RestController
public class CacheController {


    @Autowired
    private CacheService cacheService;

    @GetMapping("demo01/{number}")
    public Object demo01(@PathVariable("number") int number) {
        return cacheService.demo01(number);
    }
}

启动类上开启缓存功能

@SpringBootApplication
@EnableCaching
public class SpringCacheApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(SpringCacheApplication.class, args);

    }
}

我们来访问以下localhost:8080/demo01/2时,控制台的输出结果
在这里插入图片描述

在这里插入图片描述
当我们多次刷新界面后,会发现控制台没有任何输出,说明我们是从redis取的数据。

我们通过命令登录redis 看一下我们的数据是不是存在了redis中。
在这里插入图片描述发现我们的数据已经存在redis中了。

但是我们看到的数据不是很友好,这是因为默认的序列化方式为jdk的序列化方式。
我们可以修改一下value的序列化方式。
我们加一个redis的配置文件RedisConfig.java

@Configuration
public class RedisConfig {

    @Bean
    public RedisCacheManagerBuilderCustomizer myRedisCacheManagerBuilderCustomizer() {
        return (builder) -> builder
                .withCacheConfiguration("demo01",
                        RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(RedisSerializationContext
                                .SerializationPair
                                .fromSerializer(RedisSerializer.json())));


    }

}

重启服务后我们再来测试一下,这次我们输入4。

在这里插入图片描述

登录redis服务器后查看一下结果:

在这里插入图片描述
第二次我们输入的4,获取的结果为16,符合我们的序列化要求。

  1. key

我们可以修改掉默认key的生产策略,比如我们要用 ""来作为我们自定义的key,i为我们方法的参数。

@Cacheable(value = "demo01",key = "'<'+ #i +'>'")
public  int  demo02(int i){
    System.out.println("=========》模拟查询数据库获取数据");
    return ++i;
}

我们来测试一下
在这里插入图片描述
登录redis 获取一下我们的key ,可以成功获取到我们的值2。
在这里插入图片描述

  1. KeyGenerator
    通过自定义KeyGenerator 实现修改key的生成策略,要求key的格式为:方法名-第一个参数名
    例如 demo01-5。
@Bean
    public KeyGenerator myKeyGenerator(){
        return  new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {

                //方法名-第一个参数值
                return method.getName()+"-"+params[0].toString();
            }
        };
    }

在写个demo03的service和对应的controller

@Cacheable(value = "demo01",keyGenerator = "myKeyGenerator")
public  int  demo03(int i){
    System.out.println("=========》模拟查询数据库获取数据");
    return --i;
}
 @GetMapping("demo03/{number}")
    public Object demo03(@PathVariable("number") int number) {
        return cacheService.demo03(number);
    }

重启服务后我们测试下:
在这里插入图片描述
同样,登录redis 验证下我们的结果:
在这里插入图片描述
符合我们的预期,demo01 为缓存组件的名字,demo03-1 即为我们自定义的格式(方法名-第一个参数名)。

  1. condition
    符合condition条件的情况下才缓存。例如我们当参数i的值大于8的时候才进行缓存。

service代码

 @Cacheable(value = "demo01",condition = "#i>8")
    public  int  demo04(int i){
        System.out.println("=========》模拟查询数据库获取数据");
        return --i;
    }

controller代码

 @GetMapping("demo04/{number}")
    public Object demo04(@PathVariable("number") int number) {
        return cacheService.demo04(number);
    }

在浏览器进行测试:
在这里插入图片描述
登录redis ,查看结果,正常情况下应该获取不到,因为我们的i=6,不满足我们的i>8的条件

在这里插入图片描述
结果符合预期,没有获取到值。
我们修改下i的值改为9,符合我们设置的大于8的条件,再来测试下
在这里插入图片描述
查看redis结果:
在这里插入图片描述
发现redis中已经缓存了我们的数据,结果符合我们设置的condition条件。

  1. unless
    当unless条件为true时,结果不会被缓存。例如我们当参数i的值大于100的时候不进行缓存。

service代码:

 @Cacheable(value = "demo01",unless = "#i>100")
    public  int  demo05(int i){
        System.out.println("=========》模拟查询数据库获取数据");
        return --i;
    }

controller代码:
打开浏览器测试:

在这里插入图片描述

输入88 ,不满足我们的unless条件,因此结果应该被缓存
登录redis查看:
在这里插入图片描述
确实,结果已经缓存了。
我们在来测试下102,正常满足unless条件,因此结果应该不会被缓存。
浏览器测试:
在这里插入图片描述

登录redis 查看缓存结果:
在这里插入图片描述
符合设置的unless条件,结果因为没有被缓存。
7. sync
是否使用异步模式。默认false,以同步的方式将方法返回的结果存在缓存中。

接下来会给大家补充上其他注解的详细用法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值