SpringBoot整合Redis及Redis简介

前言

由于版本原因,SpringBoot2.0整合Redis和低版本的SpringBoot不太一样,此方案基于Srping Boot 2.x

Linux下Redis安装

整合

maven 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 下面的不用加,用于分布式共享session的配置 -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

分布式共享session参考:参考

配置文件application.properties

# Redis 数据库索引
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=maxzhao
# 连接池最大连接数
spring.redis.jedis.pool.max-active=1000
# 连接池最大阻塞等待时间,负值没有限制
spring.redis.jedis.pool.max-wait=-1
# 连接池中最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=2
# 超时时间 毫秒
spring.redis.timeout=1000

注入

@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
// StringRedisTemplate是继承RedisTemplate的,
// RedisTemplate在StringRedisTemplate中泛型定义为String

StringRedisTemplate 源码

public class StringRedisTemplate extends RedisTemplate<String, String> {
    public StringRedisTemplate() {
        this.setKeySerializer(RedisSerializer.string());
        this.setValueSerializer(RedisSerializer.string());
        this.setHashKeySerializer(RedisSerializer.string());
        this.setHashValueSerializer(RedisSerializer.string());
    }

    public StringRedisTemplate(RedisConnectionFactory connectionFactory) {
        this();
        this.setConnectionFactory(connectionFactory);
        this.afterPropertiesSet();
    }

    protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
        return new DefaultStringRedisConnection(connection);
    }
}

StringRedisTemplate 测试

这里用的是Springboot Test

@RunWith(SpringRunner.class)
@SpringBootTest(classes = IttestApplication.class)
public class RedisTest {


    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void testRedisTemplate() {
        String prefix = "maxzhao:redisTemplate:";
        HashOperations hashOperations = redisTemplate.opsForHash();
        ValueOperations valueOps = redisTemplate.opsForValue();
        ListOperations listOps = redisTemplate.opsForList();
        SetOperations setOps = redisTemplate.opsForSet();
        ZSetOperations zSetOps = redisTemplate.opsForZSet();
        GeoOperations geoOperations = redisTemplate.opsForGeo();
        ClusterOperations clusterOperations = redisTemplate.opsForCluster();
        Map map = Arrays.stream(new String[]{"a", "B"}).collect(Collectors.toMap(Function.identity(), Function.identity()));
        hashOperations.putAll(prefix + "hash", map);
    }

    @Test
    public void testStringRedisTemplate() {
        String prefix = "maxzhao:stringRedisTemplate:";
        HashOperations hashOperations = stringRedisTemplate.opsForHash();
        hashOperations.putAll(prefix + "hash", Arrays.stream(new String[]{"a", "b"}).collect(Collectors.toMap(Function.identity(), Function.identity())));
        hashOperations.putAll(prefix + "hash", Arrays.stream(new String[]{"c", "d"}).collect(Collectors.toMap(Function.identity(), Function.identity())));
        hashOperations.putAll(prefix + "hash", Arrays.stream(new String[]{"e", "f"}).collect(Collectors.toMap(Function.identity(), Function.identity())));
        hashOperations.put(prefix + "hash", "max", "maxvalue");// a b c d e f max
        hashOperations.get(prefix + "hash", "max");// maxvalue
        hashOperations.delete(prefix + "hash", "f");// return 1  database:a b c d e max
        hashOperations.delete(prefix + "hash", "c", "d");// return 2  database:a b e max
        hashOperations.hasKey(prefix + "hash", "max");//return true
        hashOperations.values(prefix + "hash");// return map object
        ValueOperations valueOperations = stringRedisTemplate.opsForValue();
        valueOperations.set(prefix + "value", "value");
        valueOperations.set(prefix + "value", "valueTest");//value 被覆盖
        valueOperations.get(prefix + "value");// return valueTest

        ListOperations listOps = stringRedisTemplate.opsForList();
//        listOps.remove(prefix + "list", listOps.size(prefix + "list"), 1);
        listOps.leftPush(prefix + "list", "A");
        listOps.leftPush(prefix + "list", "B");
        listOps.rightPush(prefix + "list", "C", "D");//只有 1:B  2:A
        listOps.leftPush(prefix + "list", "C");
        listOps.leftPush(prefix + "list", "D");//return 3  1:D 2:C 3:A
        listOps.range(prefix + "list", 0, listOps.size(prefix + "list"));//return 3  0:D 1:C 2:A   list下标从0开始
        listOps.leftPop(prefix + "list");//只有   1:A 返回的为B
        listOps.leftPush(prefix + "list2", "A");
        listOps.leftPush(prefix + "list2", "B");//只有 1:B  2:A
        listOps.rightPush(prefix + "list2", "C");//只有 1:B  2:A 3 C

        // set 是无序的,所有pop等获取value的操作,得到结果可能不同
        SetOperations setOps = stringRedisTemplate.opsForSet();
        setOps.add(prefix + "set", "A");//return 1
        setOps.add(prefix + "set", "A");//return 0
        setOps.add(prefix + "set", "B");//return 1
        setOps.difference(prefix + "set", "A");//return HashSet  A,B
        setOps.isMember(prefix + "set", "A");//return true
        setOps.isMember(prefix + "set", "C");//return false
        setOps.members(prefix + "set");//return HashSet  A,B
        setOps.pop(prefix + "set");// 出序列并删除 1个
        setOps.add(prefix + "set", "A","B", "C", "D", "E");//return 5
        setOps.pop(prefix + "set", 2);// 出序列并删除 2个
        setOps.add(prefix + "set", "A","B", "C", "D", "E");
        setOps.move(prefix + "set", "D", "A");//return  true  database=BCE
        // 把当前key=set的c值,move到 key=set1
        setOps.move(prefix + "set", "C", prefix + "set1");//return  true
        setOps.remove(prefix + "set", "C", "D");//删除
        // 有序的set
        ZSetOperations zSetOps = stringRedisTemplate.opsForZSet();

        GeoOperations geoOperations = stringRedisTemplate.opsForGeo();
        // 只有jedis 和 lettuce 支持Redis Cluster。
        ClusterOperations clusterOperations = stringRedisTemplate.opsForCluster();
        System.out.println("====================");
    }
}

Redis Cluster

Enabling Redis Cluster

<p>集群的支持是基于非集群通讯构建的。RedisClusterConnection 是RedisConnection 的一个扩展,用来处理和Redis Cluster的通讯,转换错误信息到Spring DAO异常层。RedisClusterConnection 是通过RedisConnectionFactory 创建的,该工程的创建要依据于RedisClusterConfiguration配置。</p>

Example 1. Sample RedisConnectionFactory Configuration for Redis Cluster

@Component
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class ClusterConfigurationProperties {

    /*
     * spring.redis.cluster.nodes[0] = 127.0.0.1:7379
     * spring.redis.cluster.nodes[1] = 127.0.0.1:7380
     * ...
     */
    List<String> nodes;

    /**
     * Get initial collection of known cluster nodes in format {@code host:port}.
     *
     * @return
     */
    public List<String> getNodes() {
        return nodes;
    }

    public void setNodes(List<String> nodes) {
        this.nodes = nodes;
    }
}

@Configuration
public class AppConfig {

    /**
     * Type safe representation of application.properties
     */
    @Autowired ClusterConfigurationProperties clusterProperties;

    public @Bean RedisConnectionFactory connectionFactory() {

        return new JedisConnectionFactory(
            new RedisClusterConfiguration(clusterProperties.getNodes()));
    }
}

通过配置文件配置:

# 这个初始化的配置为驱动库指定了一组初始化集群节点。集群可以在线修改配置,但修改结果只会保存在本驱动的内存中,不会写入到配置文件中。
spring.redis.cluster.nodes: Comma delimited list of host:port pairs.
spring.redis.cluster.max-redirects: Number of allowed cluster redirections.

参考:官方文档中文版(个人站)

参考:官方文档中文版(官网)

参考:官方文档中文版(官网doc)

参考:SpringBoot的配置文件

RedisTemplate源码


public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
    // 是否支持事物,必须通过设置setEnableTransactionSupport(true)显式地为使用中的每个RedisTemplate启用事务支持这将强制将正在使用的重断开绑定到当前线程触发MULTI。如果事务完成时没有错误,则调用EXEC,否则丢弃。一旦在MULTI中,RedisConnection将对写操作进行排队,所有只读操作(例如键)都将通过管道传输到一个新的(非线程绑定的)RedisConnection。
    private boolean enableTransactionSupport = false;
    // 有一个this.createRedisConnectionProxy代理
    private boolean exposeConnection = false;
    // afterPropertiesSet()方法用到,此方法允许bean实例在设置了所有bean属性后执行总体配置的验证和最终初始化。
    private boolean initialized = false;
    // 默认序列化
    private boolean enableDefaultSerializer = true;
    // 默认使用JdkSerializationRedisSerializer序列化
    @Nullable
    private RedisSerializer<?> defaultSerializer;
    @Nullable
    private ClassLoader classLoader;
    // 默认使用 this.defaultSerializer 序列化
    @Nullable
    private RedisSerializer keySerializer = null;
    // 默认使用 this.defaultSerializer 序列化
    @Nullable
    private RedisSerializer valueSerializer = null;
    // 默认使用 this.defaultSerializer 序列化
    @Nullable
    private RedisSerializer hashKeySerializer = null;
    // 默认使用 this.defaultSerializer 序列化
    @Nullable
    private RedisSerializer hashValueSerializer = null;
    // 默认使用 new StringRedisSerializer(StandardCharsets.UTF_8)
    private RedisSerializer<String> stringSerializer = RedisSerializer.string();
    // 用于执行Redis脚本的ScriptExecutor
    @Nullable
    private ScriptExecutor<K> scriptExecutor;
    @Nullable
    private ValueOperations<K, V> valueOps;
    @Nullable
    private ListOperations<K, V> listOps;
    @Nullable
    private SetOperations<K, V> setOps;
    @Nullable
    private ZSetOperations<K, V> zSetOps;
    @Nullable
    private GeoOperations<K, V> geoOps;
    @Nullable
    private HyperLogLogOperations<K, V> hllOps;

    public RedisTemplate() {
    }

    public void afterPropertiesSet() ;
    // 在连接中执行给定的操作对象
    @Nullable
    public <T> T execute(RedisCallback<T> action) ;
    // 在连接中执行给定的操作对象,该对象可以公开,也可以不公开。
    @Nullable
    public <T> T execute(RedisCallback<T> action, boolean exposeConnection) ;
    // 在可公开或不可公开的连接中执行给定的操作对象。此外,可以对连接进行流水线操作。注意,管道的结果被丢弃(使其适合只写的场景)。有道翻译
    @Nullable
    public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline);
    // 执行一个Redis会话。允许在同一个会话中执行多个操作,通过RedisOperations.multi()和RedisOperations.watch(Collection)操作启用“事务”功能。
    public <T> T execute(SessionCallback<T> session) ;
    //在管道连接上执行给定的Redis会话。允许流水线处理事务。注意,回调函数不能返回非空值,因为它被管道覆盖。
    public List<Object> executePipelined(SessionCallback<?> session) ;
    // 自定义序列化
    public List<Object> executePipelined(SessionCallback<?> session, @Nullable RedisSerializer<?> resultSerializer) ;
    // 在管道连接上执行给定的操作对象,返回结果。注意,回调函数不能返回非空值,因为它被管道覆盖。此方法将使用默认的序列化器反序列化结果
    public List<Object> executePipelined(RedisCallback<?> action) ;
    // 自定义序列化
    public List<Object> executePipelined(RedisCallback<?> action, @Nullable RedisSerializer<?> resultSerializer) ;
    public <T> T execute(RedisScript<T> script, List<K> keys, Object... args) ;
    public <T> T execute(RedisScript<T> script, RedisSerializer<?> argsSerializer, RedisSerializer<T> resultSerializer, List<K> keys, Object... args) ;
    public <T extends Closeable> T executeWithStickyConnection(RedisCallback<T> callback) ;
    private Object executeSession(SessionCallback<?> session) {
        return session.execute(this);
    }
    protected RedisConnection createRedisConnectionProxy(RedisConnection pm) ;
    protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) ;
    @Nullable
    protected <T> T postProcessResult(@Nullable T result, RedisConnection conn, boolean existingConnection) ;
    public boolean isExposeConnection();
    public void setExposeConnection(boolean exposeConnection) ;
    public boolean isEnableDefaultSerializer() ;
    public void setEnableDefaultSerializer(boolean enableDefaultSerializer) ;
    @Nullable
    public RedisSerializer<?> getDefaultSerializer() ;
    public void setDefaultSerializer(RedisSerializer<?> serializer) ;
    public void setKeySerializer(RedisSerializer<?> serializer) ;
    public RedisSerializer<?> getKeySerializer() ;
    public void setValueSerializer(RedisSerializer<?> serializer) ;
    public RedisSerializer<?> getValueSerializer() ;
    public RedisSerializer<?> getHashKeySerializer() ;
    public void setHashKeySerializer(RedisSerializer<?> hashKeySerializer) ;
    public RedisSerializer<?> getHashValueSerializer() ;
    public void setHashValueSerializer(RedisSerializer<?> hashValueSerializer) ;
    public RedisSerializer<String> getStringSerializer() ;
    public void setStringSerializer(RedisSerializer<String> stringSerializer) ;
    public void setScriptExecutor(ScriptExecutor<K> scriptExecutor) ;
    private byte[] rawKey(Object key) ;
    private byte[] rawString(String key) ;
    private byte[] rawValue(Object value) ;
    private byte[][] rawKeys(Collection<K> keys) ; 
    private K deserializeKey(byte[] value) ;
    @Nullable
    private List<Object> deserializeMixedResults(@Nullable List<Object> rawValues, @Nullable RedisSerializer valueSerializer, @Nullable RedisSerializer hashKeySerializer, @Nullable RedisSerializer hashValueSerializer) ;
    private Set<?> deserializeSet(Set rawSet, @Nullable RedisSerializer valueSerializer) ;
    private Set<TypedTuple<V>> convertTupleValues(Set<Tuple> rawValues, @Nullable RedisSerializer valueSerializer) ;
    public List<Object> exec() ;
    public List<Object> exec(RedisSerializer<?> valueSerializer) ;
    protected List<Object> execRaw() ;
    public Boolean delete(K key) ;
    public Long delete(Collection<K> keys) ;
    public Boolean unlink(K key) ;
    public Long unlink(Collection<K> keys) ;
    public Boolean hasKey(K key) ;
    public Long countExistingKeys(Collection<K> keys) ;
    public Boolean expire(K key, long timeout, TimeUnit unit) ;
    public Boolean expireAt(K key, Date date) ;
    public void convertAndSend(String channel, Object message);
    public Long getExpire(K key) ;
    public Long getExpire(K key, TimeUnit timeUnit) ;
    public Set<K> keys(K pattern) ;
    public Boolean persist(K key) ;
    public Boolean move(K key, int dbIndex) ;
    public K randomKey() ;
    public void rename(K oldKey, K newKey) ;
    public Boolean renameIfAbsent(K oldKey, K newKey) ;
    public DataType type(K key);
    public byte[] dump(K key) ;
    public void restore(K key, byte[] value, long timeToLive, TimeUnit unit, boolean replace) ;
    public void multi() ;
    public void discard() ;
    public void watch(K key) ;
    public void watch(Collection<K> keys) ;
    public void unwatch() ;
    public List<V> sort(SortQuery<K> query) ;
    public <T> List<T> sort(SortQuery<K> query, @Nullable RedisSerializer<T> resultSerializer) ;
    public <T> List<T> sort(SortQuery<K> query, BulkMapper<T, V> bulkMapper) ;
    public <T, S> List<T> sort(SortQuery<K> query, BulkMapper<T, S> bulkMapper, @Nullable RedisSerializer<S> resultSerializer) ;
    public Long sort(SortQuery<K> query, K storeKey) ;
    public void killClient(String host, int port);
    public List<RedisClientInfo> getClientList() ;
    public void slaveOf(String host, int port) ;
    public void slaveOfNoOne() ;

本文地址:SpringBoot整合Redis及Redis简介

推荐
SpringBoot的配置文件

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容