All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.luues.redis.single.config.RedisConfig Maven / Gradle / Ivy
package com.luues.redis.single.config;
import cn.luues.tool.crypto.CryptoUtils;
import cn.luues.tool.json.JsonUtils;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.luues.exception.core.exception.RedisException;
import com.luues.redis.config.CustomizedRedisCacheManager;
import com.luues.redis.config.JedisConfig;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
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.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import redis.clients.jedis.*;
import java.lang.reflect.Field;
import java.time.Duration;
import java.util.*;
/**
* redis配置类
*
* @author Mr-Wu ON 2019/05/07
**/
@ConditionalOnExpression("!'${spring.redis.host:null}'.equals('null')")
@Component(value = "redis_config")
@ConfigurationProperties(prefix = "spring.redis")
@EnableCaching//开启注解
@Data
@Slf4j(topic = "c.l.r.s.c.r")
public class RedisConfig extends CachingConfigurerSupport {
private Integer maxIdle = 300;
private Integer maxTotal = 1000;
private Integer maxWaitMillis = 1000;
//JedisPool中连接的空闲时间阈值,当达到这个阈值时,空闲连接就会被移除。Redis的默认值是30分钟,太长,所以JedisPoolConfig的默认值是1分钟;
private Integer minEvictableIdleTimeMillis = 60000;
//每次检测时,取多少个连接进行检测。如果设置成-1,就表示检测所有链接
private Integer numTestsPerEvictionRun = -1;
//检测空闲连接的周期
private Long timeBetweenEvictionRunsMillis = (long)30000;
private Boolean testOnBorrow = true;
private Boolean testOnReturn = true;
private Boolean testWhileIdle = true;
private String host;
private Integer port = 6379;
private Integer timeout = 2000;
private String prefix;
private String password;
private Integer database = 0;
public String getHost() {
return CryptoUtils.initDecrypt(host);
}
public String getPrefix() {
return CryptoUtils.initDecrypt(prefix);
}
public String getPassword() {
return CryptoUtils.initDecrypt(password);
}
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空闲数
jedisPoolConfig.setMaxIdle(maxIdle);
// 连接池的最大数据库连接数
jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立连接等待时间
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
jedisPoolConfig.setMinEvictableIdleTimeMillis(maxWaitMillis);
// 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在return一个jedis实例时,是否提前进行validate操作
jedisPoolConfig.setTestOnReturn(testOnReturn);
jedisPoolConfig.setTestOnCreate(true);
// 在空闲时检查有效性, 默认false
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
log.info("jedis - Starting...");
return jedisPoolConfig;
}
@Bean
@Qualifier(value = "jedisShardInfos")
public List jedisShardInfos() throws NoSuchFieldException, IllegalAccessException {
List shards = new ArrayList();
JedisShardInfo jedisShardInfo = new JedisShardInfo(getHost(), getPort());
if(Strings.isNotBlank(password)){
jedisShardInfo.setPassword(getPassword());
}
Class extends JedisShardInfo> clz = jedisShardInfo.getClass();
Field declaredField = clz.getDeclaredField("db");
declaredField.setAccessible(true);
declaredField.set(jedisShardInfo, database);
shards.add(jedisShardInfo);
return shards;
}
@Bean
public ShardedJedisPool shardedJedisPool(JedisPoolConfig jedisPoolConfig, @Qualifier(value = "jedisShardInfos") List jedisShardInfos) {
ShardedJedisPool shardedJedisPool = new ShardedJedisPool(jedisPoolConfig, jedisShardInfos);
return shardedJedisPool;
}
@Bean
public JedisPool jedisPool(JedisPoolConfig jedisPoolConfig) throws RedisException {
JedisPool jedisPool = null;
if(Strings.isNotBlank(password)){
jedisPool = new JedisPool(jedisPoolConfig, getHost(), port, timeout, getPassword(), database);
} else {
jedisPool = new JedisPool(jedisPoolConfig, getHost(), port, timeout, null, database);
}
try {
jedisPool.getResource().get("-test-");
log.info("jedis - Start completed.");
}catch (Exception e){
log.error("jedis - Start fail. error:{}", e.getMessage());
log.info("config:{}", JsonUtils.toJson(this));
throw new RedisException("redis start fail");
}
return jedisPool;
}
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(getHost());
redisStandaloneConfiguration.setDatabase(database);
redisStandaloneConfiguration.setPort(port);
if(Strings.isNotBlank(password)){
redisStandaloneConfiguration.setPassword(RedisPassword.of(getPassword()));
}
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean({CacheManagerProperties.class})
@DependsOn({"springContextHolder"})
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, CacheManagerProperties cacheManagerProperties) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(cacheManagerProperties.getDefaultCacheMillis()).disableCachingNullValues();
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
Set cacheNames = new HashSet<>();
Map cacheConfig = new HashMap<>();
if (null != cacheManagerProperties.getCaches()) {
for (Map.Entry entry : cacheManagerProperties.getCaches().entrySet()) {
cacheNames.add(entry.getKey());
cacheConfig.put(entry.getKey(), redisCacheConfiguration.entryTtl(entry.getValue()));
}
}
if(!JedisConfig.getJedisConfig().isCusCache())
return RedisCacheManager.builder(redisCacheWriter)
.cacheDefaults(redisCacheConfiguration)
.initialCacheNames(cacheNames)
.withInitialCacheConfigurations(cacheConfig)
.build();
ObjectMapper objectMapper = new ObjectMapper();
redisCacheConfiguration = redisCacheConfiguration
.computePrefixWith(cacheName -> (getPrefix().endsWith(":") ? getPrefix() : getPrefix().concat(":")).concat(cacheName).concat(":"))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(createJackson2JsonRedisSerializer(objectMapper)));
return new CustomizedRedisCacheManager(redisCacheWriter, redisCacheConfiguration, cacheConfig);
}
/**
* 缓存的序列化
*
* @param
* @param redisConnectionFactory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
ObjectMapper objectMapper = new ObjectMapper();
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(60 * 60))
.disableCachingNullValues()
.computePrefixWith(cacheName -> (getPrefix().endsWith(":") ? getPrefix() : getPrefix().concat(":")).concat(cacheName).concat(":"))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(createJackson2JsonRedisSerializer(objectMapper)));
return new CustomizedRedisCacheManager(redisConnectionFactory, cacheConfiguration);
//改变CacheManager的创建方式,原方式如下
// return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build();
}
private RedisSerializer createJackson2JsonRedisSerializer(ObjectMapper objectMapper) {
// TODO Auto-generated method stub\
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 解决jackson2无法反序列化LocalDateTime的问题
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
serializer.setObjectMapper(objectMapper);
return serializer;
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(keySerializer());
redisTemplate.setHashKeySerializer(keySerializer());
redisTemplate.setValueSerializer(valueSerializer());
redisTemplate.setHashValueSerializer(valueSerializer());
return redisTemplate;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
stringRedisTemplate.setKeySerializer(keySerializer());
return stringRedisTemplate;
}
/**
* 用于spring session,防止每次创建一个线程
* @return
*/
@Bean
public ThreadPoolTaskExecutor springSessionRedisTaskExecutor() {
ThreadPoolTaskExecutor springSessionRedisTaskExecutor = new ThreadPoolTaskExecutor();
springSessionRedisTaskExecutor.setCorePoolSize(8);
springSessionRedisTaskExecutor.setMaxPoolSize(16);
springSessionRedisTaskExecutor.setKeepAliveSeconds(10);
springSessionRedisTaskExecutor.setQueueCapacity(1000);
springSessionRedisTaskExecutor.setThreadNamePrefix("Spring session redis executor thread: ");
return springSessionRedisTaskExecutor;
}
private RedisSerializer keySerializer() {
return new StringRedisSerializer();
}
private RedisSerializer valueSerializer() {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 解决jackson2无法反序列化LocalDateTime的问题
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return jackson2JsonRedisSerializer/*new GenericJackson2JsonRedisSerializer()*/;
}
}