前言
在理论springboot集成redis应用过程中,针对不同类型的业务数据,可能存在不同的dbindex中,例如token存储db0,redis全局锁存储dbindex1,须要咱们对RedisTemplate操作进行扩大,反对单次操作不同的dbindex
计划
零碎加载时初始化依据redis应用库的dbindex,初始化对应个数的RedisTemplate,调用时依据dbindex获取对应的操作对象实例,本次实现是将15个db全副初始化
RedisRegist
初始化redis的Factory,线程池配置及RedisTemplate,StringRedisTemplate的Bean对象
public class RedisRegist implements EnvironmentAware,ImportBeanDefinitionRegistrar { private static final Logger logger = LoggerFactory.getLogger(RedisRegist.class); private static Map<String, Object> 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; //依据多个库实例化出多个连接池和Template for (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<LettuceConnectionFactory> 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<String, RedisTemplate> redisTemplateMap; private Map<String, StringRedisTemplate> stringRedisTemplateMap; public RedisManage(Map<String, RedisTemplate> redisTemplateMap, Map<String, StringRedisTemplate> 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<String, RedisTemplate> getRedisTemplateMap() { return redisTemplateMap; } public Map<String, StringRedisTemplate> getStringRedisTemplateMap() { return stringRedisTemplateMap; }}
RedisConfig
将操作类Bean对象注入道RedisManage中
@AutoConfigureBefore({RedisAutoConfiguration.class})@Import(RedisRegist.class)@Configurationpublic 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<String, RedisTemplate> redisTemplateMap = new HashMap<>(); Map<String, StringRedisTemplate> 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<String,RedisTemplate> initRedisTemplate(){ RedisEntity redisEntity; try { redisEntity = binder.bind("spring.redis", RedisEntity.class).get(); } catch (NoSuchElementException e) { throw new RuntimeException("Failed to configure spring.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封装具体相干操作调用
@Componentpublic class RedisUtil { @Autowired private RedisManage redisManage; private int defatuDBIndex= 0; public void redisTemplateSet(String key, Object value){ ValueOperations<Object, Object> ops = redisManage.redisTemplate(defatuDBIndex).opsForValue(); ops.set(key, value); } public void redisTemplateSet(String key, Object value,int dbIndex){ ValueOperations<Object, Object> ops = redisManage.redisTemplate(dbIndex).opsForValue(); ops.set(key, value); } public Object redisTemplateGet(String key){ ValueOperations<Object, Object> ops = redisManage.redisTemplate(defatuDBIndex).opsForValue(); return ops.get(key); } public Object redisTemplateGet(String key,int dbIndex){ ValueOperations<Object, Object> ops = redisManage.redisTemplate(dbIndex).opsForValue(); return ops.get(key); } public void redisTemplateRemove(String key){ ValueOperations<Object, Object> ops = redisManage.redisTemplate(defatuDBIndex).opsForValue(); ops.getOperations().delete(key); } public void redisTemplateRemove(String key,int dbIndex){ ValueOperations<Object, Object> ops = redisManage.redisTemplate(dbIndex).opsForValue(); ops.getOperations().delete(key); } public void redisTemplateSetForList(String key, Map<String,Object> map){ HashOperations<Object, Object,Object> ops = redisManage.redisTemplate(defatuDBIndex).opsForHash(); ops.putAll(key,map); } public void redisTemplateSetForList(String key, Map<String,Object> map,int dbIndex){ HashOperations<Object, Object,Object> ops = redisManage.redisTemplate(dbIndex).opsForHash(); ops.putAll(key,map); } public void redisTemplateSetForList(String key, String hashKey,Object value){ HashOperations<Object, Object,Object> ops = redisManage.redisTemplate(defatuDBIndex).opsForHash(); ops.put(key,hashKey,value); } public void redisTemplateSetForList(String key, String hashKey,Object value,int dbIndex){ HashOperations<Object, Object,Object> ops = redisManage.redisTemplate(dbIndex).opsForHash(); ops.put(key,hashKey,value); } public Map<Object, Object> redisTemplateGetForList(String key){ HashOperations<Object, Object,Object> ops = redisManage.redisTemplate(defatuDBIndex).opsForHash(); return ops.entries(key); } public Map<Object, Object> redisTemplateGetForList(String key,int dbIndex){ HashOperations<Object, Object,Object> ops = redisManage.redisTemplate(dbIndex).opsForHash(); return ops.entries(key); } public Object redisTemplateGetForList(String key,String hasKey){ HashOperations<Object, Object,Object> ops = redisManage.redisTemplate(defatuDBIndex).opsForHash(); return ops.get(key,hasKey); } public Object redisTemplateGetForList(String key,String hasKey,int dbIndex){ HashOperations<Object, Object,Object> ops = redisManage.redisTemplate(dbIndex).opsForHash(); return ops.get(key,hasKey); } public void setExpire(String key,long timeout, final TimeUnit unit,int dbIndex){ redisManage.redisTemplate(dbIndex).expire(key,timeout, unit); } public void 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; }}