Spring Boot整合Redis

Spring Boot整合Redis

文章目录

  • Spring Boot整合Redis
    • 1.引入依赖
    • 2.配置yml文件
    • 3.Redis配置类


完全按照此篇文章的配置,可以不做任何修改,即可无限衔接大部分项目需求

1.引入依赖

 		<!-- 开启boot对redis的支持-->
 		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 开启redis对管理session-->
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

2.配置yml文件

代码如下(示例):集群或哨兵模式部署配置请参考我的上一篇文章《Redis的部署安装以及集群哨兵模式》

spring:
 redies: #redies缓存
   host: 192.168.1.233
   port: 6397
   password:
   timeout: 60000 #连接超时时间(毫秒)
   database: 0 # Redis数据库索引(默认为0)
   lettuce:
     shutdown-timeout: 100 #在关闭客户端连接之前最大等待任务结束时间  默认100ms
     pool:
       max-active: 8 #连接池最大连接数
       min-idle: 2 #最小空闲数
       max-idle: 20 #最大空闲数
       max-wait: 60000 #最大建立连接等待时间
  #集群或哨兵根据自己实际业务需求
  #cluster: #redies 集群配置
  #  maxRedirects: 3 # 最大集群连接数
  #	 nodes:192.168.1.234:6380,192.168.1.235:6381
  #sentinel: #哨兵配置
  #  master: redisMaster #监听的master名字
  #  nodes: 192.168.1.234:26379,192.168.1.235:26379,192.168.1.233:26379

3.Redis配置类

@Data
@Configuration
@EnableCaching
@ConfigurationProperties(prefix = "spring.redis")
public class RedisConfig extends CachingConfigurerSupport {

    private String host;
    private String password;
    private int port;
    private int timeout;
    private int database;
    @Value("${spring.redis.lettuce.pool.min-idle}")
    private int minIdle;
    @Value("${spring.redis.lettuce.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.lettuce.pool.max-wait}")
    private int maxWait;
    @Value("${spring.redis.lettuce.pool.max-active}")
    private int maxActive;

    /**
     * redis 序列化策略 ,通常情况下key值采用String序列化策略
     * StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。StringRedisSerializer
     * RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。JdkSerializationRedisSerializer
     *
     * @param lettuceConnectionFactory
     * @return
     */
    @Bean
    @Primary
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);
        redisTemplate.setHashKeySerializer(redisSerializer);
        GenericJackson2JsonRedisSerializer genericFastJsonRedisSerializer = getJackson2();
        redisTemplate.setDefaultSerializer(genericFastJsonRedisSerializer);
        redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericFastJsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    private GenericJackson2JsonRedisSerializer getJackson2() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
        objectMapper.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);
        objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY);
        SimpleFilterProvider filterProvider = new SimpleFilterProvider();
        filterProvider.setDefaultFilter(SimpleBeanPropertyFilter.serializeAll());
        objectMapper.setFilterProvider(filterProvider);
        return new GenericJackson2JsonRedisSerializer(objectMapper);
    }
    /**
     * SpringCache缓存管理器(SpringBoot 2.x),根据自身业务决定是否使用
     * @param lettuceConnectionFactory
     * @return
     */
    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory) {
        GenericJackson2JsonRedisSerializer redisSerializer = getJackson2();
        RedisSerializationContext.SerializationPair serializationPair
                = RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer);
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
                .defaultCacheConfig().entryTtl(Duration.ofMinutes(30))//缓存失效时间
                .serializeValuesWith(serializationPair);
        return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(lettuceConnectionFactory))
                .cacheDefaults(redisCacheConfiguration).build();
    }
    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        return getJackson2();
    }

 
    /**
     * boot2.x,将默认的jedis替换成了lettuce
     *
     * @return
     */
    @Bean(destroyMethod = "destroy")
    @Primary
    public LettuceConnectionFactory lettuceConnectionFactory() {
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMinIdle(minIdle);
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);
        LettuceConnectionFactory factory;
        if (StrUtil.isNotEmpty(master)) {
            //lettuce默认没有节点自动刷新机制,需要开启集群拓扑刷新和周期拓扑刷新(boot 2.3.x+ 可在yml配置)
            ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
                    .enableAllAdaptiveRefreshTriggers() // 开启全部自适应刷新, 自适应刷新不开启,Redis集群变更时将会导致连接异常
                    .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(5))  // 自适应刷新超时时间(默认30秒)
                    .enablePeriodicRefresh(Duration.ofSeconds(5))  // 开周期刷新, 默认关闭,开启后时间为60秒
                    .build();
            ClusterClientOptions clientOptions = ClusterClientOptions.builder()
                    .topologyRefreshOptions(clusterTopologyRefreshOptions)
                    .build();
            LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                    .commandTimeout(Duration.ofMillis(timeout))
//                    .readFrom(ReadFrom.MASTER_PREFERRED) //优先从副本读取
                    .poolConfig(genericObjectPoolConfig)
                    .clientOptions(clientOptions) //自适应集群拓扑刷新和周期拓扑刷新
                    .build();
            factory = new LettuceConnectionFactory(redisSentinelConfiguration(), clientConfig);
        } else if (StrUtil.isNotEmpty(clusterNodes)) {
            ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
                    .enableAllAdaptiveRefreshTriggers() // 开启全部自适应刷新, 自适应刷新不开启,Redis集群变更时将会导致连接异常
                    .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(5))  // 自适应刷新超时时间(默认30秒)
                    .enablePeriodicRefresh(Duration.ofSeconds(5))  // 开周期刷新, 默认关闭,开启后时间为60秒
                    .build();
            ClusterClientOptions clientOptions = ClusterClientOptions.builder()
                    .topologyRefreshOptions(clusterTopologyRefreshOptions)
                    .build();
            LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                    .commandTimeout(Duration.ofMillis(timeout))
                    .poolConfig(genericObjectPoolConfig)
                    .clientOptions(clientOptions) //自适应集群拓扑刷新和周期拓扑刷新
                    .build();
            factory = new LettuceConnectionFactory(redisClusterConfiguration(), clientConfig);
        } else {
            LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                    .commandTimeout(Duration.ofMillis(timeout))
                    .poolConfig(genericObjectPoolConfig)
                    .build();
            factory = new LettuceConnectionFactory(redisStandaloneConfiguration(), clientConfig);
        }
        factory.setShareNativeConnection(false); //是否允许多个线程操作共用同一个缓存连接,默认true,false时每个操作都将开辟新的连接
        factory.resetConnection(); // 重置底层共享连接, 在接下来的访问时初始化
        return factory;
    }

    //集群模式
    @Bean
    public RedisClusterConfiguration redisClusterConfiguration() {
        RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
        redisClusterConfiguration.setMaxRedirects(maxRedirects);
        redisClusterConfiguration.setPassword(password);
        List<String> nodes = StringUtil.splitBySign(clusterNodes, ",");
        Set<RedisNode> redisNodeSet = new HashSet<>();
        nodes.forEach(url -> redisNodeSet.add(new RedisNode(url.split(":")[0].trim(), Integer.valueOf(url.split(":")[1]))));
        redisClusterConfiguration.setClusterNodes(redisNodeSet);
        return redisClusterConfiguration;
    }

    //哨兵模式
    @Bean
    public RedisSentinelConfiguration redisSentinelConfiguration() {
        RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
        RedisNode redisNode = new RedisNode(host, port);
        redisNode.setName(master);
        redisSentinelConfiguration.master(redisNode);
        redisSentinelConfiguration.setDatabase(database);
        redisSentinelConfiguration.setPassword(RedisPassword.of(password));
        //配置redis的哨兵sentinel
        Set<String> sentinelUrl = commaDelimitedListToSet(nodes);
        Set<RedisNode> redisNodeSet = new HashSet<>();
        sentinelUrl.forEach(url -> redisNodeSet.add(new RedisNode(url.split(":")[0].trim(), Integer.valueOf(url.split(":")[1]))));
        redisSentinelConfiguration.setSentinels(redisNodeSet);
        return redisSentinelConfiguration;
    }

    //单机模式
    @Bean
    public RedisStandaloneConfiguration redisStandaloneConfiguration() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(database);
        redisStandaloneConfiguration.setHostName(host);
        redisStandaloneConfiguration.setPort(port);
        redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
        return redisStandaloneConfiguration;
    }
    
    /**
     * Key生成策略
     * @return
     */
    @Bean
    public KeyGenerator wiselyKeyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName());
            sb.append(method.getName());
            for (Object obj : params) {
                sb.append(obj.toString());
            }
            return sb.toString();
        };
    }
}

你可能感兴趣的:(数据库,redis,spring,boot,数据库)