SpringBoot2.1.5 集成Redis - Go语言中文社区

SpringBoot2.1.5 集成Redis


SpringBoot2.1.5 集成Redis

在这里插入图片描述在这里插入图片描述

1.jedis和lettuce介绍

Lettuce 和 Jedis 的定位都是Redis的client

Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接

Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,因为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。

springboot2之前redis的连接池为jedis,2.0以后redis的连接池改为了lettuce,lettuce能够支持redis4,需要java8及以上。lettuce是基于netty实现的与redis进行同步和异步的通信,之前看到spring-session-data-redis里的samples已经改为使用LettuceConnectionFactory

所以下面我们看下如何来使用Lettuce来操作Redis

2.spring-boot-starter-data-redis

简单介绍下spring-boot-starter-data-redis, 通过看RedisAutoConfiguration的源码

@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})

可以知道RedisAutoConfiguration完成了对JedisConnectionFactory和LettuceConnectionFactory的自动配置。

同时RedisProperties源码中封装了对redis配置,包括jedis和lettuce

@ConfigurationProperties(
    prefix = "spring.redis"
)

private final RedisProperties.Jedis jedis = new RedisProperties.Jedis();
private final RedisProperties.Lettuce lettuce = new RedisProperties.Lettuce();

因此我们在使用时直接通过yml配置即可使用Lettuce来连接Redis,下面我们来看具体使用

3.使用Lettuce连接Redis

maven项目,引入依赖,注意lettuce连接池的使用需要引入commons-pool2依赖包

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-pool2</artifactId>
</dependency>

yml配置

spring:
  redis:
    host: ip
    port: port
    password: password
    timeout: 2000
    lettuce:
      pool:
        max-active: 8
        max-wait: 1
        max-idle: 8
        min-idle: 0

封装Redis常用方法工具类

注意:

  • 个人使用redis的k-v都是String类型,因此使用StringRedisTemplate
  • 根据个人业务需要封装了统一的RedisKeyPrefix
  • JsonUtil是自己封装的将javabean list和json互相转换的工具类

这些都可以根据自己需要去实现,我们主要来展示操作redis的接口

/**
 * <p>@filename RedisService</p>
 * <p>
 * <p>@description 封装Redis常用方法</p>
 *
 * @author llspace
 * @version 1.0
 * @since 2019/6/27 11:13
 **/
@Component
public class RedisService {

    @Autowired
    private StringRedisTemplate redisTemplate;

	/**
	 * set方法
	 */
    public <T> boolean set(RedisKeyPrefix prefix, String key, T value){
        boolean flag = false;
        try{
            ValueOperations<String, String> operations = redisTemplate.opsForValue();
            String realKey = prefix.realKey(key);
            operations.set(realKey, JsonUtil.toJSONString(value));
            //expire <= 0 表示无限期, 不设置
            if(prefix.expire() > 0){
                redisTemplate.expire(realKey, prefix.expire(), TimeUnit.SECONDS);
            }
            flag = true;
        } catch (Exception e){
            e.printStackTrace();
        }
        return flag;
    }

	/**
	 * 判断key是否存在
	 */
	public boolean exists(RedisKeyPrefix prefix, String key){
        return redisTemplate.hasKey(prefix.realKey(key));
    }

	/**
	 * 删除
	 */
    public void delete(RedisKeyPrefix prefix, String key){
        if(exists(prefix, key)){
            redisTemplate.delete(prefix.realKey(key));
        }
    }

	/**
	 * 按规则批量删除
	 */
    public void deletePattern(String pattern){
        Set<String> keys = redisTemplate.keys(pattern);
        if(keys != null && keys.size() > 0){
            redisTemplate.delete(keys);
        }
    }

	
	/**
	 * get方法,获取javabean
	 */
    public <T> T getBean(RedisKeyPrefix prefix, String key, Class<T> clazz){
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        String value = operations.get(prefix.realKey(key));
        return JsonUtil.toBean(value, clazz);
    }

	/**
	 * get方法,获取java list
	 */
    public <T> List<T> getList(RedisKeyPrefix prefix, String key, Class<T> clazz){
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        String value = operations.get(prefix.realKey(key));
        return JsonUtil.toList(value, clazz);
    }

    public Long incr(RedisKeyPrefix prefix, String key){
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        return operations.increment(prefix.realKey(key));
    }

    public Long decr(RedisKeyPrefix prefix, String key){
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        return operations.decrement(prefix.realKey(key));
    }

}

4.自定义配置注入RestTemplate

参考RedisAutoConfiguration源码

@Configuration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }

    @Bean
    @ConditionalOnMissingBean(
        name = {"redisTemplate"}
    )
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

下面我们来自定义我们的RedisConfig(key为 String类型, value为 Object类型)

/**
 * <p>@filename RedisConfig</p>
 * <p>
 * <p>@description Redis配置类</p>
 *
 * @author llspace
 * @version 1.0
 * @since 2019/6/27 13:33
 **/
@Configuration
public class RedisConfig {

    /**
     * RedisTemplate配置
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new 		        Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

具体实现的RedisSerializer还有很多,根据自己的需求选择配置即可,比如fastjson也有FastJsonRedisSerializer和GenericFastJsonRedisSerializer的实现

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u014229347/article/details/93872886
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢