【SpringCache整合Redis】

简介

Spring Cache 是 Spring 框架提供的一个缓存抽象层,用于简化应用中的缓存操作。它通过在方法执行期间将结果存储在缓存中,以便在相同的输入参数下,下一次调用时可以直接从缓存中获取结果,而不必执行相同的计算或查询操作。Spring Cache 支持多种缓存提供商,如 Ehcache、Redis、Caffeine 等,可以根据需求选择合适的缓存实现。通过使用 Spring Cache,开发人员可以轻松地添加缓存功能,提高应用的性能和响应速度。

Redis 是 Spring Cache 中最常用的缓存实现之一,有以下几个主要原因:

  • 高性能:Redis 是一个基于内存的数据存储系统,具有非常高的读写性能。它将数据存储在内存中,可以快速地读取和写入数据,适合作为缓存存储。
  • 数据结构丰富:Redis 支持多种数据结构,如字符串、哈希、列表、集合和有序集合等,这些数据结构的灵活性可以满足不同场景下的缓存需求。
  • 持久化支持:Redis 提供了持久化机制,可以将数据存储到磁盘上,以防止数据丢失。这对于缓存数据的可靠性和持久性是非常重要的。
  • 分布式支持:Redis 支持分布式部署,可以搭建多个 Redis 节点组成集群,实现数据的分片和负载均衡,提高了系统的扩展性和容错性。
  • 生态系统丰富:Redis 有一个活跃的开源社区,提供了许多与 Spring 集成的库和工具,如 Spring Data Redis、Lettuce 和 Redisson 等,这些工具可以方便地与 Spring Cache 集成,简化了开发和配置的过程。

综上所述,Redis 在性能、数据结构、持久化、分布式支持以及生态系统方面的优势,使其成为 Spring Cache 中最常用的缓存实现之一。

整合 Spring Cache

引入依赖pom.xml

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

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

配置属性application.yml

spring:
  cache:
    type: redis
    redis:
      key-prefix: 'CACHE:TABLE:'
  data:
    redis:
      host: 127.0.0.1
      port: 6379
      database: 0
      connect-timeout: 5s
      timeout: 5s
      lettuce:
        pool:
          min-idle: 0
          max-idle: 8
          max-active: 8
          max-wait: -1ms

配置RedisCacheConfiguration

默认情况下,缓存采用JDK序列化,不便于查询,这里指定使用JSON序列化

import org.springframework.boot.autoconfigure.cache.CacheProperties;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.util.StringUtils;

import static org.springframework.data.redis.serializer.StringRedisSerializer.UTF_8;

@EnableCaching
@Configuration
public class AppConfig {

    @Bean
    RedisTemplate<String, Object> provideRedisTemplate(final RedisConnectionFactory connectionFactory) {
        final RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        final GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
        serializer.configure(mapper -> {
            mapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            mapper.registerModule(new com.fasterxml.jackson.datatype.jsr310.JavaTimeModule());
        });
        template.setKeySerializer(UTF_8);
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(UTF_8);
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }

    @Bean
    RedisCacheConfiguration provideRedisCacheConfiguration (final CacheProperties cacheProperties) {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        final CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        if (StringUtils.hasText(redisProperties.getKeyPrefix())) {
            redisCacheConfiguration = redisCacheConfiguration.prefixCacheNameWith(redisProperties.getKeyPrefix());
        }

        final GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
        serializer.configure(mapper -> {
            mapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            mapper.registerModule(new com.fasterxml.jackson.datatype.jsr310.JavaTimeModule());
        });
        return redisCacheConfiguration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));
    }
}

类注解

调用get时,先判断Redis缓存中是否有数据,如果有则取缓存,否则从其他数据源读取;
调用update时,如果缓存中有数据,则清理对应数据。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class CacheService {

    private static final Logger log = LoggerFactory.getLogger(CacheService.class);

    @Cacheable(cacheNames = "CACHE_CONFIG:COLUMN:NAME", key = "#id")
    public String get(Integer id) {
        log.info("ROBOT - GET - " + id);
        return "ROBOT" + id;
    }

    @CacheEvict(cacheNames = "CACHE_CONFIG:COLUMN:NAME", key = "#id")
    public String update(Integer id) {
        log.info("ROBOT - UPDATE - " + id);
        return "ROBOT" + id;
    }
}
posted @   Bruce.Chang.Lee  阅读(422)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
历史上的今天:
2023-04-11 Jackson常用注解
点击右上角即可分享
微信分享提示