SpringBoot集成redis缓存(附缓存源码分析)

前几天学习了redis缓存,并在SpringBoot中使用了redis缓存,今天整合成一篇文章,供自已以后参考。
初学小白,也是第一次写博客,有不足的地方请大神及时指点!
—————————————————————————————————————————

预备知识

首先要了解到以下关于缓存的基本知识

Spring中的缓存

缓存接口

首先介绍两个Spring缓存中两个重要的接口:
CacheManager:缓存管理器,用于管理缓存组件(Cache)
Cache:缓存接口,用于操作缓存记录的CURD

缓存注解

Spring提供了的缓存注解,标注在方法上,方便使用基本的缓存操作。
一、@Cacheable:将方法的运行结果进行缓存,以后再有相同的数据,直接从缓存中取出,不用调用方法(缓存中有数据时,不调用方法)

CacheManager管理多个Cache组件,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字

@Cacheable属性
1.cacheNames/value:指定缓存组件的名字,以数组的方式,可以指定多个cache
2.key:缓存数据使用的key
键值对:默认使用方法参数的值—方法的返回值
编写SpEL:#参数名 = #a0 = #p0 = root.args[0] = 参数的值
3.keyGenerator:key的生成器,可以自己指定key的生成器组件id
key/keyGenerator:两者二选一
4.cacheManager:指定缓存管理器,或者cacheResolver指定获取解析器
5.condition:指定符合的条件 条件满足才进行缓存
6.unless:否定缓存,当unless指定的条件为true,方法的返回值就不会被缓存
例如:可以根据获取结果来进行判断:unless = “#result == null”
7.sync:是否使用异步模式

二、@CachePut:修改了数据库的某个数据,同时更新缓存(既调用方法,又更新缓存数据)

运行时机:
1.先调用目标方法
2.将目标方法的结果缓存起来

注意:使用时,与@Cacheable的key要相同,才能把缓存中数据更新。

三、@CacheEvict:缓存清除

@CacheEvict属性:
1.key:指定要清除的数据
2.allEntries = true:指定清除这个缓存中所有数据(默认是false)
3.beforeInvocation = true:缓存的清除是否在方法之前执行(默认是false)
如果方法发生异常,缓存也会清除

整合redis缓存

了解了关于缓存的知识内容后,下面我将正式介绍SpringBoot中将如何使用redis做缓存。
我的SpringBoot版本为:v2.0.5.RELEASE

1.引入redis的starter依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
	<exclusions>
		<exclusion>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</exclusion>
		<exclusion>
			<groupId>io.lettuce</groupId>
			<artifactId>lettuce-core</artifactId>
		</exclusion>
	</exclusions>
</dependency>

在Spring中默认使用的是SimpleCacheConfiguration类中的CacheManager来创建Cache来做为缓存组件。
而引入redis依赖后,使用的是RedisCacheConfiguration类中的RedisCacheManager来创建RedisCache来做为缓存组件。

2.配置redis

在配置文件中配置如下参数(我是在application.yml中配置的)

# REDIS (RedisProperties)
  # Redis数据库索引(默认为0)
  redis:
      database: 0 
      timeout: 2000 
      # Redis服务器地址
      host: 127.0.0.1
      # Redis服务器连接端口
      port: 6379  
      # Redis服务器连接密码(默认为空)
      password:  
      # 连接池最大连接数(使用负值表示没有限制)
      pool: 
        max-active: 8  
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1  
        # 连接池中的最大空闲连接
        max-idle: 8  
        # 连接池中的最小空闲连接
        min-idle: 0  

配置完之后,redis的自动配置就可以生效了。
图片中可以看到在RedisAutoConfiguration.java中,加了RedisTemplate组件,用来操作redis。
RedisAutoConfiguration中的RedisTemplate组件
那么如何直接操作redis呢?
大家都知道redis有五大数据类型,我分别介绍RedisTemplate如何操作这五大数据类型:

  • redisTemplate.opsForValue()(String字符串)
  • redisTemplate.opsForList(List列表)
  • redisTemplate.opsForSet(Set集合)
  • redisTemplate.opsForHash(Hash散列)
  • redisTemplate.opsForZSet(ZSet有序集合)

3.新建一个redisConfig类,进行相关bean的配置:

存储对象时,默认是使用jdk序列化机制,将序列化后的数据存入redis中,所以需要将实体类中实现序列化接口。
想以json方式存储数据,进行如下配置:

package com.gitee.rock.base.config;


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.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

	@Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(factory);

        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSeial.setObjectMapper(om);

        // 值采用json序列化
        template.setValueSerializer(jacksonSeial);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());

        // 设置hash key 和value序列化模式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();

        return template;
    }
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
		RedisCacheManager cacheManager = RedisCacheManager.create(factory);
        return cacheManager;
    }
}

4.将RedisTemplate注入使用

以上便是我整合的redis缓存,新手上路,还请大神多多指点!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值