All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.soento.redis.config.DefaultRedisConfig Maven / Gradle / Ivy

package com.soento.redis.config;

import com.soento.core.consts.Constants;
import com.soento.core.util.AesUtil;
import com.soento.core.util.JsonUtil;
import com.soento.core.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
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.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author soento
 */
@Slf4j
@ConfigurationProperties(prefix = "soento")
public class DefaultRedisConfig implements InitializingBean {

    private Map redis = new LinkedHashMap<>();

    private Map redisConnectionFactory = new LinkedHashMap<>();
    private Map> redisTemplate = new LinkedHashMap<>();
    private Map stringRedisTemplate = new LinkedHashMap<>();
    private Map cacheManager = new LinkedHashMap<>();

    @Autowired
    private RedisProperties basicProperties;
    @Autowired
    private DefaultListableBeanFactory defaultListableBeanFactory;

    @Override
    public void afterPropertiesSet() throws Exception {
        log.debug(" init RedisProperties start ");
        if (!redis.containsKey(Constants.DEFAULT_REDIS_ALIAS)) {
            RedisPropertiesWrapper properties = new RedisPropertiesWrapper();
            properties.setHost(basicProperties.getHost());
            properties.setPort(basicProperties.getPort());
            properties.setPassword(basicProperties.getPassword());
            properties.setDatabase(basicProperties.getDatabase());
            if (basicProperties.getTimeout() != null) {
                properties.setTimeout(basicProperties.getTimeout());
            }
            if (basicProperties.getCluster() != null) {
                properties.setCluster(basicProperties.getCluster());
            }
            if (basicProperties.getSentinel() != null) {
                properties.setSentinel(basicProperties.getSentinel());
            }
            if (basicProperties.getLettuce() != null) {
                properties.setLettuce(basicProperties.getLettuce());
            }
            redis.put(Constants.DEFAULT_REDIS_ALIAS, properties);
        }
        redis.entrySet().forEach(entry -> {
            redis.put(entry.getKey(), afterPropertiesSet(entry.getValue()));
        });
        log.debug(" init RedisProperties end ");

        log.debug(" init RedisConnectionFactory start ");
        redis.entrySet().forEach(entry -> {
            redisConnectionFactory.put(entry.getKey(), buildConnectionFactory(entry.getKey(), entry.getValue()));
        });
        registerBean("RedisConnectionFactory", redisConnectionFactory);
        log.debug(" init RedisConnectionFactory end ");

        log.debug(" init RedisTemplate start ");
        redisConnectionFactory.entrySet().forEach(entry -> {
            redisTemplate.put(entry.getKey(), buildRedisTemplate(entry.getValue()));
        });
        registerBean("RedisTemplate", redisTemplate);
        log.debug(" init RedisTemplate end ");

        log.debug(" init StringRedisTemplate start ");
        redisConnectionFactory.entrySet().forEach(entry -> {
            stringRedisTemplate.put(entry.getKey(), buildStringRedisTemplate(entry.getValue()));
        });
        registerBean("StringRedisTemplate", stringRedisTemplate);
        log.debug(" init StringRedisTemplate end ");

        log.debug(" init CacheManager start ");
        redisConnectionFactory.entrySet().forEach(entry -> {
            cacheManager.put(entry.getKey(), buildCacheManager(entry.getValue(), redis.get(entry.getKey())));
        });
        registerBean("CacheManager", cacheManager);
        log.debug(" init CacheManager end ");
    }

    private  void registerBean(String name, Map beanMap) {
        beanMap.entrySet().forEach(entry -> {
            String beanName = entry.getKey() + name;
            defaultListableBeanFactory.registerSingleton(beanName, entry.getValue());
            log.debug(" register {} , Class : {}", beanName, entry.getValue().getClass());
        });
    }

    private RedisPropertiesWrapper afterPropertiesSet(RedisPropertiesWrapper properties) {
        if (StringUtil.isNotBlank(properties.getPassword())) {
            properties.setPassword(AesUtil.decryptByEcbPkcs7(properties.getPassword(), properties.getKey()));
        }
        if (properties.getJedis() == null) {
            properties.setJedis(new RedisProperties.Jedis());
        }
        if (properties.getSentinel() == null) {
            properties.setSentinel(new RedisProperties.Sentinel());
        }
        if (properties.getCluster() == null) {
            properties.setCluster(new RedisProperties.Cluster());
        }
        if (properties.getLettuce() == null) {
            properties.setLettuce(new RedisProperties.Lettuce());
        }
        return properties;
    }

    private RedisConnectionFactory buildConnectionFactory(String alias, RedisPropertiesWrapper properties) {
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        if (properties.getLettuce() != null && properties.getLettuce().getPool() != null) {
            poolConfig.setMaxIdle(properties.getLettuce().getPool().getMaxIdle());
            poolConfig.setMinIdle(properties.getLettuce().getPool().getMinIdle());
            poolConfig.setMaxTotal(properties.getLettuce().getPool().getMaxActive());
            poolConfig.setMaxWaitMillis(properties.getLettuce().getPool().getMaxWait().toMillis());
        }
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder()
                .commandTimeout(properties.getTimeout());
        builder.shutdownTimeout(properties.getLettuce().getShutdownTimeout());
        builder.poolConfig(poolConfig);
        LettuceClientConfiguration clientConfiguration = builder.build();

        RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration(properties.getHost(), properties.getPort());
        standaloneConfiguration.setDatabase(properties.getDatabase());
        standaloneConfiguration.setPassword(RedisPassword.of(properties.getPassword()));

        LettuceConnectionFactory factory = new LettuceConnectionFactory(standaloneConfiguration, clientConfiguration);
        if (!Constants.DEFAULT_REDIS_ALIAS.equals(alias)) {
            factory.afterPropertiesSet();
        }
        return factory;
    }

    private RedisTemplate buildRedisTemplate(RedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate();
        template.setConnectionFactory(factory);
        template.setKeySerializer(objectRedisSerializer());
        template.setValueSerializer(objectRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    private StringRedisTemplate buildStringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(factory);
        return template;
    }

    private CacheManager buildCacheManager(RedisConnectionFactory factory, RedisPropertiesWrapper properties) {
        RedisSerializationContext.SerializationPair serializationPair = RedisSerializationContext.SerializationPair.fromSerializer(objectRedisSerializer());
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(properties.getCacheSeconds()))
                .serializeValuesWith(serializationPair);
        return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory))
                .cacheDefaults(redisCacheConfiguration).build();
    }

    private RedisSerializer objectRedisSerializer() {
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
        serializer.setObjectMapper(JsonUtil.mapper());
        return serializer;
    }

    public RedisPropertiesWrapper getRedis(String alias) {
        return redis.get(alias);
    }

    public Map getRedis() {
        return redis;
    }

    public void setRedis(Map redis) {
        this.redis = redis;
    }

    public Map getRedisConnectionFactory() {
        return redisConnectionFactory;
    }

    public RedisConnectionFactory getRedisConnectionFactory(String alias) {
        return redisConnectionFactory.get(alias);
    }

    public Map> getRedisTemplate() {
        return redisTemplate;
    }

    public RedisTemplate getRedisTemplate(String alias) {
        return redisTemplate.get(alias);
    }

    public Map getStringRedisTemplate() {
        return stringRedisTemplate;
    }

    public StringRedisTemplate getStringRedisTemplate(String alias) {
        return stringRedisTemplate.get(alias);
    }

    public Map getCacheManager() {
        return cacheManager;
    }

    public CacheManager getCacheManager(String alias) {
        return cacheManager.get(alias);
    }
}