You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Redis持久化的Spring Session启用本地缓存?

Spring Session Redis 本地二级缓存实现方案

核心思路

为Spring Session会话数据添加本地二级缓存,实现先查本地缓存,未命中再查Redis的逻辑,同时保证本地缓存与Redis数据的一致性。针对你之前出现的StatefulRedisConnection缺失问题,可通过Spring Data Redis的LettuceConnectionFactory获取原生连接来构建Lettuce的CacheFrontend。

具体实现步骤

1. 完善Redis配置类,添加本地缓存相关Bean

保留你原有的redisConnectionFactory配置,新增以下Bean实现二级缓存逻辑:

@Configuration(proxyBeanMethods = false)
@EnableRedisHttpSession
public class RedisConfig {

    // 原有的redisConnectionFactory方法保持不变
    @Bean
    LettuceConnectionFactory redisConnectionFactory() throws Exception {
        // 你的原有代码省略
    }

    // 获取Lettuce原生连接,解决StatefulRedisConnection缺失问题
    @Bean
    StatefulRedisConnection<String, Object> statefulRedisConnection(LettuceConnectionFactory connectionFactory) {
        return connectionFactory.getNativeConnection();
    }

    // 构建二级缓存前端:本地缓存(Caffeine) + Redis后端
    @Bean
    CacheFrontend<String, Object> sessionCacheFrontend(StatefulRedisConnection<String, Object> connection) {
        // 本地缓存配置:最大1000条,30分钟无访问过期
        Cache<String, Object> localCache = Caffeine.newBuilder()
                .maximumSize(1000)
                .expireAfterAccess(Duration.ofMinutes(30))
                .build();

        // Redis缓存后端
        RedisCache<String, Object> redisCache = RedisCache.create(connection.sync());

        // 组合二级缓存:优先查本地,未命中自动查Redis并同步到本地
        return CacheFrontend.compose(localCache, redisCache);
    }

    // 自定义RedisTemplate,封装二级缓存操作
    @Bean
    @Primary // 让Spring Session优先使用该模板
    RedisTemplate<String, Object> sessionRedisTemplate(LettuceConnectionFactory connectionFactory, CacheFrontend<String, Object> cacheFrontend) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        // 替换默认ValueOperations为带二级缓存的实现
        template.setValueOperations(new CachingValueOperations(template, cacheFrontend));
        return template;
    }

    // 自定义ValueOperations,整合CacheFrontend的缓存逻辑
    static class CachingValueOperations extends DefaultValueOperations<String, Object> {
        private final CacheFrontend<String, Object> cacheFrontend;

        public CachingValueOperations(RedisTemplate<String, Object> template, CacheFrontend<String, Object> cacheFrontend) {
            super(template);
            this.cacheFrontend = cacheFrontend;
        }

        @Override
        public Object get(Object key) {
            try {
                return cacheFrontend.get((String) key);
            } catch (CacheLoader.ValueRetrievalException e) {
                return null;
            }
        }

        @Override
        public void set(String key, Object value) {
            cacheFrontend.put(key, value);
        }

        @Override
        public void delete(Object key) {
            cacheFrontend.remove((String) key);
        }
    }
}

2. 配置本地缓存依赖(以Caffeine为例)

在Maven的pom.xml中添加Caffeine依赖:

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

3. 验证逻辑

  • 会话读取:首次读取会从Redis加载并写入本地缓存,后续读取直接命中本地缓存
  • 会话更新/删除:操作会同时同步到本地缓存和Redis,保证数据一致性

关键细节说明

  • CacheFrontend.compose自动实现了二级缓存的读写逻辑,无需手动处理缓存同步
  • 自定义CachingValueOperations让Spring Session的会话操作无缝适配二级缓存,无需修改业务代码
  • 通过LettuceConnectionFactory.getNativeConnection()获取原生连接,解决了之前的StatefulRedisConnection缺失异常

内容的提问来源于stack exchange,提问作者coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:43:18