前言

在理论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;    }}