在springboot2.x中集成redis

在springboot2.x中集成redis

在springboot中集成redis可以用两种配置方法,一种是基于java代码的配置方法,一种是通过xml配置文件的实现的配置方法;此为在java代码上的配置过程;

一、在pom文件导入依赖

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

二、在application.yml文件中添加

spring:
  redis:
   	 database: 0
     host: 127.0.0.1
     port: 6379
     password: 123456

(或 在application.properties上添加)

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

三、redis配置类:RedisConfig

  1. RedisConfig类继承CachingConfigurerSupport;

  2. @Configuration声明RedisConfig为配置类

​ @EnableCaching声明启用缓存

@Configuration
@EnableCaching
  1. 配置redis 缓存管理器bean:CacheManger

  2. 配置 redis 连接工厂bean:JedisConnectionFactory

  3. 配置 redis模板bean:RedisTeamplate

  4. 配置序列化键生成器:KeyGenerator

package com.tensor.ai.config.cache;


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    /** * 默认情况下,key 值存在问题,当方法入参相同时,key 值也相同,这样会造成不同的方法读取相同的缓存,从而造成异常 * 修改后的 key 值为 className + methodName + 参数值列表,可以支持使用 @Cacheable 时不指定 Key * * @return */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                StringBuilder sb = new StringBuilder();
                sb.append(o.getClass().getName());
                sb.append(method.getName());
                for (Object obj : objects) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    @Bean
    public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {

        RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(redisTemplate.getConnectionFactory());

        // 本示例中,使用StringRedisSerializer来序列化和反序列化redis的 key值
        RedisSerializationContext.SerializationPair keySerializationPair = RedisSerializationContext.SerializationPair.fromSerializer(
                new StringRedisSerializer());

        // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的 value值
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        RedisSerializationContext.SerializationPair valueSerializationPair = RedisSerializationContext.SerializationPair.fromSerializer(
                jackson2JsonRedisSerializer);

        // 构造一个RedisCache的配置对象,设置缓存过期时间和Key、Value的序列化机制
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeKeysWith(keySerializationPair).serializeValuesWith(valueSerializationPair);
        return new RedisCacheManager(writer, config);
    }

// @Bean
// public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
// StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(factory);
// stringRedisTemplate.afterPropertiesSet();
// return stringRedisTemplate;
// }

}

四、使用缓存

  1. 在*Service接口上添加注解@CacheConfig;

  2. 方法上的注解
    @Cacheable ,返回类型不可以为void ,先查缓存再调用方法,使用方法查数据库之后将数据保存到缓存;
    @CachePut ,返回类型不可以为void,每次都会执行方法,并将结果存入指定的缓存中
    @CacheEvict,是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。

package com.keyi.ss.decode.service;


import com.jay.vito.storage.service.EntityCRUDService;
import com.keyi.ss.decode.domain.DecodeTask;
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 java.util.List;

@CacheConfig(cacheNames = "decodeTask")
public interface DecodeTaskService extends EntityCRUDService<DecodeTask, Long> {


    @Cacheable(value = "decodeValueById", key = "#p0")
    DecodeTask getDecodeTask(String id);

    @Cacheable()
    DecodeTask getDecodeTask();

    @CacheEvict
    @Override
    void delete(Long entityId);


    @CachePut()//方法执行之后,将结果缓存到缓存
    @Override
    DecodeTask save(DecodeTask entity);

    @CachePut
    @Override
    DecodeTask updateNotNull(DecodeTask entity);

    @Cacheable
    @Override
    List<DecodeTask> getAll();

}

五、测试结果

在这里插入图片描述

六、参考

spring cache

参考:https://my.oschina.net/dengfuwei/blog/1616221

spring cache 使用redis做缓存

参考:https://www.jianshu.com/p/8eb8893cf292

参考:https://www.jianshu.com/p/19628db2e7ef

参考:https://mp.weixin.qq.com/s/dFnP3URKidfwwFU5gCYAHw