SpringBoot实现redis切换dbindex

前言 在实际springboot集成redis使用过程中,针对不同类型的业务数据,可能存在不同的dbindex中,例如token存储db0,redis全局锁存储dbindex1,需要我们对RedisTemplate操作进行扩展,支持单次操作不同的dbindex
方案 系统加载时初始化根据redis使用库的dbindex,初始化对应个数的RedisTemplate,调用时根据dbindex获取对应的操作对象实例,本次实现是将15个db全部初始化
RedisRegist 【SpringBoot实现redis切换dbindex】初始化redis的Factory,线程池配置及RedisTemplate,StringRedisTemplate的Bean对象

public class RedisRegist implements EnvironmentAware,ImportBeanDefinitionRegistrar { private static final Logger logger = LoggerFactory.getLogger(RedisRegist.class); private static Map registerBean = new ConcurrentHashMap<>(); private Environment environment; private Binder binder; @Override public void setEnvironment(Environment environment) { this.environment = environment; this.binder = Binder.get(this.environment); }@Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { RedisEntity redisEntity; try { redisEntity = binder.bind("spring.redis", RedisEntity.class).get(); } catch (NoSuchElementException e) { logger.error("redis not setting."); return; } boolean onPrimary = true; //根据多个库实例化出多个连接池和Templatefor (int i = 0; i < 15; i++) { int database = i; //单机模式 RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(); configuration.setHostName(String.valueOf(redisEntity.getHost())); configuration.setPort(Integer.parseInt(String.valueOf(redisEntity.getPort()))); configuration.setDatabase(database); String password = redisEntity.getPassword(); if (password != null && !"".equals(password)) { RedisPassword redisPassword = RedisPassword.of(password); configuration.setPassword(redisPassword); }//池配置 GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); RedisProperties.Pool pool = redisEntity.getLettuce().getPoolEntity(); genericObjectPoolConfig.setMaxIdle(pool.getMaxIdle()); genericObjectPoolConfig.setMaxTotal(pool.getMaxActive()); genericObjectPoolConfig.setMinIdle(pool.getMinIdle()); if (pool.getMaxWait() != null) { genericObjectPoolConfig.setMaxWaitMillis(pool.getMaxWait().toMillis()); } Supplier lettuceConnectionFactorySupplier = () -> { LettuceConnectionFactory factory = (LettuceConnectionFactory) registerBean.get("LettuceConnectionFactory" + database); if (factory != null) { return factory; } LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder(); Duration shutdownTimeout = redisEntity.getLettuce().getShutdownTimeout(); if(shutdownTimeout == null){ shutdownTimeout = redisEntity.getTimeout(); } if (shutdownTimeout != null) { builder.shutdownTimeout(shutdownTimeout); } LettuceClientConfiguration clientConfiguration = builder.poolConfig(genericObjectPoolConfig).build(); factory = new LettuceConnectionFactory(configuration, clientConfiguration); registerBean.put("LettuceConnectionFactory" + database, factory); return factory; }; LettuceConnectionFactory lettuceConnectionFactory = lettuceConnectionFactorySupplier.get(); BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(LettuceConnectionFactory.class, lettuceConnectionFactorySupplier); AbstractBeanDefinition factoryBean = builder.getRawBeanDefinition(); factoryBean.setPrimary(onPrimary); registry.registerBeanDefinition("lettuceConnectionFactory" + database, factoryBean); // StringRedisTemplate GenericBeanDefinition stringRedisTemplate = new GenericBeanDefinition(); stringRedisTemplate.setBeanClass(StringRedisTemplate.class); ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); constructorArgumentValues.addIndexedArgumentValue(0, lettuceConnectionFactory); stringRedisTemplate.setConstructorArgumentValues(constructorArgumentValues); stringRedisTemplate.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME); registry.registerBeanDefinition("stringRedisTemplate" + database, stringRedisTemplate); // 定义RedisTemplate对象 GenericBeanDefinition redisTemplate = new GenericBeanDefinition(); redisTemplate.setBeanClass(RedisTemplate.class); redisTemplate.getPropertyValues().add("connectionFactory", lettuceConnectionFactory); redisTemplate.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME); RedisSerializer stringSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // key采用String的序列化方式,value采用json序列化方式 redisTemplate.getPropertyValues().add("keySerializer",new StringRedisSerializer()); redisTemplate.getPropertyValues().add("hashKeySerializer",stringSerializer); redisTemplate.getPropertyValues().add("valueSerializer",jackson2JsonRedisSerializer); redisTemplate.getPropertyValues().add("hashValueSerializer",stringSerializer); //注册Bean registry.registerBeanDefinition("redisTemplate" + database, redisTemplate); //logger.info("Registration redis ({}) !", database); if (onPrimary) { onPrimary = false; } } }}

RedisManage RedisTemplate,StringRedisTemplate的Bean对象统一管理定义
public class RedisManage { private Map redisTemplateMap; private Map stringRedisTemplateMap; public RedisManage(Map redisTemplateMap, Map stringRedisTemplateMap) { this.redisTemplateMap = redisTemplateMap; this.stringRedisTemplateMap = stringRedisTemplateMap; }public RedisTemplate redisTemplate(int dbIndex) { RedisTemplate redisTemplate = redisTemplateMap.get("redisTemplate" + dbIndex); return redisTemplate; }public StringRedisTemplate stringRedisTemplate(int dbIndex) { StringRedisTemplate stringRedisTemplate = stringRedisTemplateMap.get("stringRedisTemplate" + dbIndex); stringRedisTemplate.setEnableTransactionSupport(true); return stringRedisTemplate; }public Map getRedisTemplateMap() { return redisTemplateMap; }public Map getStringRedisTemplateMap() { return stringRedisTemplateMap; }}

RedisConfig 将操作类Bean对象注入道RedisManage中
@AutoConfigureBefore({RedisAutoConfiguration.class}) @Import(RedisRegist.class) @Configuration public class RedisConfig implements EnvironmentAware, ApplicationContextAware { private static final Logger logger = LoggerFactory.getLogger(RedisConfig.class); private static String key1 = "redisTemplate"; private static String key2 = "stringRedisTemplate"; Map redisTemplateMap = new HashMap<>(); Map stringRedisTemplateMap = new HashMap<>(); private Binder binder; private Environment environment; private ApplicationContext applicationContext; @Override public void setEnvironment(Environment environment) { this.environment = environment; this.binder = Binder.get(this.environment); } @PostConstruct public Map initRedisTemplate(){ RedisEntity redisEntity; try { redisEntity = binder.bind("spring.redis", RedisEntity.class).get(); } catch (NoSuchElementException e) { throw new RuntimeException("Failed to configurespring.redis: 'spring.redis' attribute is not specified and no embedded redis could be configured."); }for (int i=0; i<15; i++){ int database = i; String key = key1 + database; RedisTemplate redisTemplate = applicationContext.getBean(key , RedisTemplate.class); if(redisTemplate != null){ redisTemplateMap.put(key , redisTemplate); }key = key2 + database; if(stringRedisTemplateMap != null){ StringRedisTemplate stringRedisTemplate = applicationContext.getBean(key , StringRedisTemplate.class); stringRedisTemplateMap.put(key , stringRedisTemplate); } }if(redisTemplateMap.size() == 0 && stringRedisTemplateMap.size() == 0){ throw new RuntimeException("load redisTemplate failure , please check spring.redis property config!!!"); } return redisTemplateMap; }@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; }@Bean public RedisManage redisManage(){ return new RedisManage(redisTemplateMap , stringRedisTemplateMap); } }

RedisUtil 调用RedisManage封装具体相关操作调用
@Component public class RedisUtil { @Autowired private RedisManage redisManage; private int defatuDBIndex= 0; public void redisTemplateSet(String key, Object value){ ValueOperations ops = redisManage.redisTemplate(defatuDBIndex).opsForValue(); ops.set(key, value); }public void redisTemplateSet(String key, Object value,int dbIndex){ ValueOperations ops = redisManage.redisTemplate(dbIndex).opsForValue(); ops.set(key, value); }public Object redisTemplateGet(String key){ ValueOperations ops = redisManage.redisTemplate(defatuDBIndex).opsForValue(); return ops.get(key); }public Object redisTemplateGet(String key,int dbIndex){ ValueOperations ops = redisManage.redisTemplate(dbIndex).opsForValue(); return ops.get(key); }public void redisTemplateRemove(String key){ ValueOperations ops = redisManage.redisTemplate(defatuDBIndex).opsForValue(); ops.getOperations().delete(key); }public void redisTemplateRemove(String key,int dbIndex){ ValueOperations ops = redisManage.redisTemplate(dbIndex).opsForValue(); ops.getOperations().delete(key); }public void redisTemplateSetForList(String key, Map map){ HashOperations ops = redisManage.redisTemplate(defatuDBIndex).opsForHash(); ops.putAll(key,map); }public void redisTemplateSetForList(String key, Map map,int dbIndex){ HashOperations ops = redisManage.redisTemplate(dbIndex).opsForHash(); ops.putAll(key,map); }public void redisTemplateSetForList(String key, String hashKey,Object value){ HashOperations ops = redisManage.redisTemplate(defatuDBIndex).opsForHash(); ops.put(key,hashKey,value); }public void redisTemplateSetForList(String key, String hashKey,Object value,int dbIndex){ HashOperations ops = redisManage.redisTemplate(dbIndex).opsForHash(); ops.put(key,hashKey,value); }public Map redisTemplateGetForList(String key){ HashOperations ops = redisManage.redisTemplate(defatuDBIndex).opsForHash(); return ops.entries(key); }public Map redisTemplateGetForList(String key,int dbIndex){ HashOperations ops = redisManage.redisTemplate(dbIndex).opsForHash(); return ops.entries(key); }public Object redisTemplateGetForList(String key,String hasKey){ HashOperations ops = redisManage.redisTemplate(defatuDBIndex).opsForHash(); return ops.get(key,hasKey); }public Object redisTemplateGetForList(String key,String hasKey,int dbIndex){ HashOperations ops = redisManage.redisTemplate(dbIndex).opsForHash(); return ops.get(key,hasKey); }publicvoid setExpire(String key,long timeout, final TimeUnit unit,int dbIndex){ redisManage.redisTemplate(dbIndex).expire(key,timeout, unit); }publicvoid setExpire(String key,long timeout, final TimeUnit unit){ redisManage.redisTemplate(defatuDBIndex).expire(key,timeout, unit); }public boolean isValid(String key){ boolean flag = false; if(redisManage.redisTemplate(defatuDBIndex).hasKey(key)){ if( redisManage.redisTemplate(defatuDBIndex).getExpire(key,TimeUnit.SECONDS)>0){ flag = true; } } return flag; }public boolean isValid(String key,int dbIndex){ boolean flag = false; if(redisManage.redisTemplate(dbIndex).hasKey(key)){ if( redisManage.redisTemplate(dbIndex).getExpire(key,TimeUnit.SECONDS)>0){ flag = true; } } return flag; } }

    推荐阅读