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.
matrix.boot.redis.config.RedisAutoConfiguration Maven / Gradle / Ivy
package matrix.boot.redis.config;
import matrix.boot.common.exception.ServiceException;
import matrix.boot.common.utils.AssertUtil;
import matrix.boot.common.utils.StringUtil;
import matrix.boot.redis.properties.RedisProperties;
import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter;
import org.springframework.boot.autoconfigure.AutoConfigurationMetadata;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.time.Duration;
import java.util.*;
/**
* redis自动装配类
*
* @author WangCheng
*/
@EnableConfigurationProperties(RedisProperties.class)
@ConditionalOnProperty(value = {"matrix.redis.enabled"})
@EnableCaching
public class RedisAutoConfiguration {
/**
* 默认参数 @Cacheable注解用
*/
public static final String DEFAULT_VALUE = "DEFAULT";
/**
* 默认key生成方式 @Cacheable注解用
*/
public static final String DEFAULT_GENERATOR = "wiselyKeyGenerator";
/**
* redis配置
*/
private final RedisProperties redisProperties;
public RedisAutoConfiguration(RedisProperties redisProperties) {
this.redisProperties = redisProperties;
}
/**
* 创建redis模板
*
* @param factory redis连接工厂
* @param keyClassType 键类型
* @param valueClassType 值类型
* @param 键泛型
* @param 值泛型
* @return redis模板
*/
private static RedisTemplate createRedisTemplate(RedisConnectionFactory factory, Class keyClassType, Class valueClassType) {
RedisTemplate redisTemplate = new RedisTemplate<>();
//定义json序列化
RedisSerializer redisSerializer = new GenericJackson2JsonRedisSerializer();
if (String.class.equals(keyClassType)) {
//如果键为String类型,设置键序列化为string序列化
RedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
} else {
//设置为json序列化
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
}
//设置值为json序列化
redisTemplate.setValueSerializer(redisSerializer);
redisTemplate.setHashValueSerializer(redisSerializer);
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
/**
* 获取redis连接工厂
*
* @return redis工厂
*/
@Bean
@Order(value = 1)
public JedisConnectionFactory redisConnectionFactory() {
JedisClientConfiguration.JedisClientConfigurationBuilder builder = JedisClientConfiguration.builder();
//设置连接超时时间
Duration duration = Duration.ofSeconds(redisProperties.getTimeout());
builder.readTimeout(duration).connectTimeout(duration);
JedisPoolConfig poolConfig = new JedisPoolConfig();
//设置最大空闲数
poolConfig.setMaxIdle(20);
//设置最大连接数
poolConfig.setMaxTotal(redisProperties.getMaxTotal());
//设置最大等待时间10s
poolConfig.setMaxWaitMillis(10000L);
builder.usePooling().poolConfig(poolConfig);
return this.getRedisConnectionFactory(builder.build());
}
/**
* 获取redis工厂
*
* @param client redis客户端
* @return redis工厂
*/
private JedisConnectionFactory getRedisConnectionFactory(JedisClientConfiguration client) {
if (redisProperties.getStandalone().isEnabled()) {
//单机模式
RedisProperties.Standalone standaloneConfig = redisProperties.getStandalone();
String hostName = standaloneConfig.getHost();
AssertUtil.notNullTip(hostName, "matrix.redis.host");
Integer database = standaloneConfig.getDatabase();
AssertUtil.notNullTip(database, "matrix.redis.database");
String password = standaloneConfig.getPassword();
String port = standaloneConfig.getPort();
AssertUtil.notNullTip(port, "matrix.redis.port");
RedisStandaloneConfiguration standalone = new RedisStandaloneConfiguration();
standalone.setHostName(hostName);
standalone.setDatabase(database);
if (!StringUtil.isEmpty(password)) {
standalone.setPassword(RedisPassword.of(password));
}
standalone.setPort(Integer.parseInt(port));
return new JedisConnectionFactory(standalone, client);
}
if (redisProperties.getSentinel().isEnabled()) {
//哨兵模式
RedisProperties.Sentinel sentinelConfig = redisProperties.getSentinel();
String master = sentinelConfig.getMaster();
AssertUtil.notNullTip(master, "matrix.redis.sentinel.master");
String nodes = sentinelConfig.getNodes();
AssertUtil.notNullTip(nodes, "matrix.redis.sentinel.nodes");
String password = sentinelConfig.getPassword();
Integer database = sentinelConfig.getDatabase();
AssertUtil.notNullTip(database, "matrix.redis.sentinel.database");
RedisSentinelConfiguration sentinel = new RedisSentinelConfiguration();
sentinel.master(master);
sentinel.setSentinels(this.parseRedisNodes(nodes));
if (!StringUtil.isEmpty(password)) {
sentinel.setPassword(RedisPassword.of(password));
}
sentinel.setDatabase(database);
return new JedisConnectionFactory(sentinel, client);
}
if (redisProperties.getCluster().isEnabled()) {
//集群模式
RedisProperties.Cluster clusterConfig = redisProperties.getCluster();
String nodes = clusterConfig.getNodes();
AssertUtil.notNullTip(nodes, "matrix.redis.cluster.nodes");
String password = clusterConfig.getPassword();
Integer maxRedirects = clusterConfig.getMaxRedirects();
AssertUtil.notNullTip(maxRedirects, "matrix.redis.cluster.max-redirects");
RedisClusterConfiguration cluster = new RedisClusterConfiguration();
cluster.setClusterNodes(this.parseRedisNodes(nodes));
if (!StringUtil.isEmpty(password)) {
cluster.setPassword(RedisPassword.of(password));
}
cluster.setMaxRedirects(maxRedirects);
return new JedisConnectionFactory(cluster, client);
}
throw new ServiceException("standalone, sentinel, cluster don't deactivate all");
}
/**
* 根据配置解析redis节点
*
* @param data 用户配置数据
* @return redis节点
*/
private List parseRedisNodes(String data) {
AssertUtil.matchRegex("([^,:]+:\\d{1,5},)*([^,:]+:\\d{1,5}){1}",
data, "格式为: host:port,host:port", null);
List nodes = new ArrayList<>();
for (String text : data.split(",")) {
if (!StringUtil.isEmpty(text)) {
String[] parts = text.split(":");
AssertUtil.state(parts.length == 2, "Must be defined as 'host:port'");
nodes.add(new RedisNode(parts[0], Integer.parseInt(parts[1])));
}
}
return nodes;
}
/**
* spring @Cacheable注解缓存管理器
*
* @param redisConnectionFactory redis连接工厂
* @return 缓存管理器
*/
@Bean
@Order(value = 2)
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
Long expire = redisProperties.getDefaultExpire();
if (expire != null) {
config = config.entryTtl(Duration.ofSeconds(expire));
}
return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();
}
/**
* spring @Cacheable key生成规则
*
* @return key规则生成器
*/
@Bean
@Order(value = 3)
public KeyGenerator wiselyKeyGenerator() {
return (target, method, params) -> {
List cacheKey = new ArrayList<>();
cacheKey.add(target.getClass().getName());
cacheKey.add(method.getName());
if (params.length > 0) {
StringBuilder sb = new StringBuilder();
for (Object obj : params) {
sb.append(obj != null ? String.valueOf(obj) : "NONE");
}
cacheKey.add(sb.toString());
}
return String.join(":", cacheKey);
};
}
/**
* 默认的stringRedisTemplate
*
* @param factory redis工厂
* @return 默认的模板
*/
@Bean(name = "redisTemplate")
@Order(value = 4)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate redisTemplate = new StringRedisTemplate();
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
/**
* 默认的objectRedisTemplate
*
* @param factory redis工厂
* @return 默认的object模板
*/
@Bean
@Order(value = 5)
public RedisTemplate objectRedisTemplate(RedisConnectionFactory factory) {
return createRedisTemplate(factory, Object.class, Object.class);
}
/**
* 默认的stringRedisTemplate
*
* @param factory redis工厂
* @return 默认的string模板
*/
@Bean
@Order(value = 6)
public RedisTemplate defaultRedisTemplate(RedisConnectionFactory factory) {
return createRedisTemplate(factory, String.class, Object.class);
}
/**
* 排除自动装配过滤器
*/
public static class ExcludeAutoConfigurationFilter implements AutoConfigurationImportFilter {
private static final Set SHOULD_SKIP = new HashSet<>(Collections.singletonList(
"org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration"));
@Override
public boolean[] match(String[] classNames, AutoConfigurationMetadata metadata) {
boolean[] matches = new boolean[classNames.length];
for (int i = 0; i < classNames.length; i++) {
matches[i] = !SHOULD_SKIP.contains(classNames[i]);
}
return matches;
}
}
}