【实用技巧】【SpringBoot + Redis】SpringBoot 启动时,注入多个RedisTemplate
1 前言
大家可能都用过缓存 Redis,有一个这样的场景比如商品中心有商品的缓存,渠道中心有渠道信息的缓存,应用端去获取这些信息的时候,我是这么想的能不能直接在应用这里把多个中心下的 Redis,我也注入进来,也就是注入多个中心的 RedisTemplate,这样应用可以先去缓存中拿,类似这样的场景哈,就是在启动的时候,注入多个RedisTemplate,来获取信息。
2 实现
首先考虑一个过程就是我 SpringBoot 在启动的时候通过读取配置文件的信息,来注入多个RedisTemplate。我这里直接上代码了哈:(连接工厂用的 LettuceConnectionFactory)
比如我这里有配置:
mul: redis: # 核心 redis core: 15 # 渠道 redis channel: 14 # 商品 redis item: 13
启动的配置类:
package com.kuku.core.sys.config; import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.AbstractEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.Iterator; import java.util.Map; /** * @author kuku * @description */ @Slf4j @Component @AutoConfigureAfter(RedisAutoConfiguration.class) public class MultiRedisConfig implements BeanDefinitionRegistryPostProcessor, EnvironmentAware { @Autowired private Environment environment; @Override public void setEnvironment(Environment environment) { // 环境变量引进来 用于获取配置 this.environment = environment; } // 多redis配置的前缀 private static final String REDIS_PREFIX = "mul.redis."; private static final String REDIS_BEAN_NAME_SUFFIX = "RedisTemplate"; @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { AbstractEnvironment standardServletEnvironment = (AbstractEnvironment) environment; // 筛选redis的配置,然后筛选出 mul.redis.的配置 进行注入 Iterator<PropertySource<?>> iterator = standardServletEnvironment.getPropertySources().iterator(); Map<String, Integer> redisMap = Maps.newHashMapWithExpectedSize(20); while (iterator.hasNext()) { PropertySource<?> source = iterator.next(); String name = source.getName(); // 从redis配置中获取配置信息 if (!name.contains("redis")) { continue; } Object o = source.getSource(); if (o instanceof Map) { for (Map.Entry<String, Object> entry : ((Map<String, Object>) o).entrySet()) { String key = entry.getKey(); if (key.startsWith(REDIS_PREFIX)) { redisMap.put(key.replace(REDIS_PREFIX, "") + REDIS_BEAN_NAME_SUFFIX, Integer.parseInt(entry.getValue().toString())); } } } } // 依次注入 if (!CollectionUtils.isEmpty(redisMap)) { redisMap.forEach((key, val) -> { log.info("--init redis template {}, database index {}", key, val); beanDefinitionRegistry.registerBeanDefinition(key, generateRedisTemplateDefinition(val)); }); } } // 生成 Bean 的定义信息 public GenericBeanDefinition generateRedisTemplateDefinition(int database) { GenericBeanDefinition definition = new GenericBeanDefinition(); definition.setBeanClass(RedisTemplate.class); // 添加属性配置 比如连接工厂(配置连接池)、默认的序列化 addPropertyValues(definition, database); return definition; } public void addPropertyValues(GenericBeanDefinition definition, int database) { RedisConnectionFactory redisConnectionFactory = getRedisConnectionFactory(database); definition.getPropertyValues().add("connectionFactory", redisConnectionFactory); // 默认序列化器 默认都采用 fastjson 来处理 key value FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); definition.getPropertyValues().add("defaultSerializer", fastJsonRedisSerializer); } /** * 是负责建立Factory的连接工厂类 * @param database * @return */ public RedisConnectionFactory getRedisConnectionFactory(int database) { // 基础配置信息 RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); redisStandaloneConfiguration.setHostName(environment.getProperty("spring.redis.host", "localhost")); redisStandaloneConfiguration.setPort(Integer.parseInt(environment.getProperty("spring.redis.port", "6379"))); redisStandaloneConfiguration.setPassword(environment.getProperty("spring.redis.password", "")); redisStandaloneConfiguration.setDatabase(database); // 连接池信息 GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); poolConfig.setMaxTotal(Integer.parseInt(environment.getProperty("spring.redis.max-total", "200"))); poolConfig.setMinIdle(Integer.parseInt(environment.getProperty("spring.redis.min-idle", "50"))); poolConfig.setMaxIdle(Integer.parseInt(environment.getProperty("spring.redis.max-idle", "150"))); LettucePoolingClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(poolConfig).build(); // 创建 LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfiguration); lettuceConnectionFactory.afterPropertiesSet(); return lettuceConnectionFactory; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { } }
启动的效果:
实际使用:
测试效果:
3 小结
就到这里哈,就是类似这样的需要注入多个 RedisTemplate的,有写的不对的地方欢迎指正哈。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了