springboot整合redis,并使用@Cacheable等注解进行缓存

注解简介

注 解 描 述
@Cacheable Spring容器会查询是否存在此缓存,未找到的话,则执行方法并进行缓存;否则直接返回缓存数据(常用于查询
@CachePut Spring容器不会查询是否存在此缓存,而是直接执行方法,然后直接缓存起来 (常用于 新增、修改
@CacheEvict 移除缓存对应的 key 的值 (常用于 删除

举例 :@Cacheable 参数详解

  • value : 缓存Key
  • cacheNames :缓存Key (和value一样,任意配置一个即可)
  • key : 可选,拼接在value后的缓存key,默认为"" ,用于动态计算(SpEL)表达式
  • condition :可选,限定条件:理解为用于使方法缓存具有条件,默认值为""

引入依赖

     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-redis</artifactId>
     </dependency>
     
     <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-lang3</artifactId>
         <version>3.10</version>
     </dependency>


自定义Redis缓存管理器

package com.redisson.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;

import java.time.Duration;

/**
 * @author TanZhong
 * @date 2022年08月01日 11:37
 */
@Slf4j
public class CustomRedisCacheManager extends RedisCacheManager {

    /**
     * 提供默认构造器
     * @param cacheWriter
     * @param defaultCacheConfiguration
     */
    public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
        super(cacheWriter, defaultCacheConfiguration);
    }


    /**
     * 重写父类createRedisCache方法
     * @param name @Cacheable中的value
     * @param cacheConfig
     * @return org.springframework.data.redis.cache.RedisCache
     */
    @Override
    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
        log.info("开始创建缓存!");
        // 名称中存在#标记进行到期时间配置
        if (!name.isEmpty() && name.contains("#")) {
            String[] SPEL = name.split("#");
            if (StringUtils.isNumeric(SPEL[1])) {
                // 配置缓存到期时间
                int cycle = Integer.parseInt(SPEL[1]);
                log.info("配置缓存到期时间成功!");
                return super.createRedisCache(SPEL[0], cacheConfig.entryTtl(Duration.ofSeconds(cycle)));
            }
        }
        return super.createRedisCache(name, cacheConfig);
    }
}


创建redis配置类

package com.redisson.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
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.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * @author TanZhong
 * @date 2022年08月01日 10:56
 */
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 创建 redisTemplate 模版
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 创建 序列化类
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        // 创建 序列化类
        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);
        template.setConnectionFactory(factory);
        // key序列化方式
        template.setKeySerializer(redisSerializer);
        // value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hashmap  key序列化
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        // hashmap  value序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }


    /**
     * Redis缓存的序列化方式使用redisTemplate.getValueSerializer(),
     * 不在使用JDK默认的序列化方式,默认1小时后过期
     * @param redisTemplate
     * @return
     */
    @Bean
    public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(60 * 60))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
        //return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
        return new CustomRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
    }
}


yml配置redis

#redis
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: aaaaBBBB
    database: 12

业务代码

    /**
     * 注解参数 value = "tan:cache:listOrder"  ==> 自定义配置了 1h后过期;
     * 注解参数 value = "tan:cache:listOrder#60"  ==> 自定义配置了 #60 代表 60s后过期;
     * @return
     */
//    @Cacheable(value = "aa", key = "'bb'")
//    @Cacheable(value = "tan:cache:listOrder", key = "targetClass + '_' + methodName")
//    @Cacheable(value = "tan:cache:listOrder#60", key = "targetClass + '_' + methodName")
    @Cacheable(value = "tan:cache:listOrder#60", key = "targetClass + '_' + methodName + '_' + #id")
    @GetMapping("/listOrder")
    public List<Map<String, Object>> listOrder(Integer id) {
        Map<String, Object> map1 = new HashMap<>(2);
        map1.put("name", "张三");
        map1.put("age", 20);

        Map<String, Object> map2 = new HashMap<>(2);
        map2.put("name", "李四");
        map2.put("age", 50);
        log.info("进行缓存!");
        return Arrays.asList(map1, map2);
    }

查看结果

请添加图片描述

  • 缓存key: tan:cache:listOrder::class com.redisson.controller.RedisDelayQueueController_listOrder
  • 缓存key: tan:cache:listOrder::class com.redisson.controller.RedisDelayQueueController_listOrder_9
    springboot整合redis,并使用@Cacheable等注解进行缓存_第1张图片

你可能感兴趣的:(redis,缓存,spring,boot)