Spring Boot 項目實戰(四)集成 Redis


一、前言

上篇介紹了接口文檔工具 Swagger 及項目監控工具 JavaMelody 的集成過程,使項目更加健壯。在 JAVA Web 項目某些場景中,我們需要用緩存解決如熱點數據訪問的性能問題,業界常用的中間件如 Memcached 、 Redis 等。相比 Memcached ,Redis 支持更豐富的數據結構。本篇將主要介紹在 Spring Boot 中集成 Redis 的過程。


二、集成 Redis

在 Spring Boot 中使用 Redis 有兩種方式:

  • 基於 RedisTemplate 類,該類是 Spring Data 提供的工具,可以直接注入使用。
  • 基於 Jedis,Jedis 是 Redis 官方推薦的面向 JAVA 的客戶端。

本文將介紹第一種使用方式。

2.1 引入依賴包

其實 Spring Boot 提供的父工程中已經包含了所依賴的 Redis jar 包,我們只需在相應模塊引入即可。第一篇我們已經提到過 demo-common 層是公用組件層,那么 Redis 相關的聲明及配置應該在該層定義。於是乎在 demo-common 層的 pom 文件中引入 Redis 的依賴包。

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

2.2 RedisTemplate 的自動配置

其實我們現在就可以在項目中注入 RedisTemplate 並使用了,至於原因,首先看下「 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;
    }
}

從源碼可以看出,Spring Boot 會自動幫我們生成了一個 RedisTemplate 及一個 StringRedisTemplate ,但是這個 RedisTemplate 的泛型是 <Object, Object> ,如果我們直接使用就需要處理各種類型轉換。所以為了方便使用,我們需要自定義一個泛型為 <String, Object> 的 RedisTemplate 。
而 @ConditionalOnMissingBean 注解的作用是在當前 Spring 上下文中不存在某個對象時,才會自動實例化一個 Bean 。因此我們可以自定義 RedisTemplate 從而替代默認的。

2.2 自定義 Redis 配置類

Spring Data 提供了若干個 Serializer ,主要包括:

  • JdkSerializationRedisSerializer — 使用 JAVA 自帶的序列化機制將對象序列化為一個字符串
  • OxmSerializer — 將對象序列化為 XML 字符串
  • Jackson2JsonRedisSerializer — 將對象序列化為 JSON 字符串

其中 RedisTemplate 默認的序列化方式是 Jdk ,雖然是效率比較高但是序列化結果的字符串是最長的。而 JSON 由於其數據格式的緊湊型,序列化結果的字符串是最小的,即占用的內存最小。所以我們選擇用 Jackson 替代默認的 Jdk 方式。

① 首先在項目父 pom 文件中定義 Jackson 的版本號且聲明 Jackson 依賴。

<properties>
    ...省略其余部分...
    <jackson.version>2.9.4</jackson.version>
</properties>
<dependencyManagement>
    <dependencies>
        ...省略其余部分...
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>${jackson.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

② 其次在 demo-common 層的 pom 文件中添加上述 Jackson 依賴。

<dependencies>
    ...省略其余部分...
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>
</dependencies>

③ 最后在 demo-common 層創建 com.example.demo.common 包,添加 Redis 目錄並在其中創建 RedisConfig 配置類。

package com.example.demo.common.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author linjian
 * @date 2019/3/2
 */
@Configuration
public class RedisConfig {

    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.findAndRegisterModules();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        // 使用 Jackson2JsonRedisSerialize 替換默認序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(factory);
        // key 采用 String 的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // hash 的 key 也采用 String 的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // value 序列化方式采用 jackson
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // hash 的 value 序列化方式采用 jackson
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

2.3 自定義 Redis 工具類

直接使用 RedisTemplate 操作 Redis 需要很多額外的代碼,最好封裝成一個工具類,使用時直接注入。
① 定義一個常用的緩存時間常量類

package com.example.demo.common.redis;

/**
 * @author linjian
 * @date 2019/3/2
 */
public class CacheTime {

    /**
     * 緩存時效 5秒鍾
     */
    public static int CACHE_EXP_FIVE_SECONDS = 5;

    /**
     * 緩存時效 1分鍾
     */
    public static int CACHE_EXP_MINUTE = 60;

    /**
     * 緩存時效 5分鍾
     */
    public static int CACHE_EXP_FIVE_MINUTES = 60 * 5;

    /**
     * 緩存時效 10分鍾
     */
    public static int CACHE_EXP_TEN_MINUTES = 60 * 10;

    /**
     * 緩存時效 15分鍾
     */
    public static int CACHE_EXP_QUARTER_MINUTES = 60 * 15;

    /**
     * 緩存時效 60分鍾
     */
    public static int CACHE_EXP_HOUR = 60 * 60;

    /**
     * 緩存時效 12小時
     */
    public static int CACHE_EXP_HALF_DAY = 12 * 60 * 60;

    /**
     * 緩存時效 1天
     */
    public static int CACHE_EXP_DAY = 3600 * 24;

    /**
     * 緩存時效 1周
     */
    public static int CACHE_EXP_WEEK = 3600 * 24 * 7;

    /**
     * 緩存時效 1月
     */
    public static int CACHE_EXP_MONTH = 3600 * 24 * 30 * 7;

    /**
     * 緩存時效 永久
     */
    public static int CACHE_EXP_FOREVER = 0;
}

② 定義工具類

package com.example.demo.common.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author linjian
 * @date 2019/3/2
 */
@Component
public class RedisClient {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 指定緩存失效時間
     *
     * @param key  鍵
     * @param time 時間(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根據key 獲取剩余過期時間
     *
     * @param key 鍵 不能為null
     * @return 時間(秒) 返回0代表為永久有效
     */
    public long ttl(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判斷key是否存在
     *
     * @param key 鍵
     * @return true 存在 false不存在
     */
    public boolean exists(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 刪除緩存
     *
     * @param key 可以傳一個值 或多個
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    /**
     * 模糊匹配批量刪除
     *
     * @param pattern 匹配的前綴
     */
    public void deleteByPattern(String pattern) {
        Set<String> keys = redisTemplate.keys(pattern);
        if (!CollectionUtils.isEmpty(keys)) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 設置指定 key 的值
     *
     * @param key   鍵
     * @param value 值
     * @param time  時間(秒) time要大於0 如果time小於等於0 將設置無限期
     * @return true成功 false 失敗
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time == CacheTime.CACHE_EXP_FOREVER) {
                redisTemplate.opsForValue().set(key, value);
            } else {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 獲取指定 key 的值
     *
     * @param key 鍵
     * @return 值
     */
    @SuppressWarnings("unchecked")
    public <T> T get(String key) {
        return key == null ? null : (T) redisTemplate.opsForValue().get(key);
    }

    /**
     * 將 key 中儲存的數字值遞增
     *
     * @param key   鍵
     * @param delta 要增加幾(大於0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta <= 0) {
            throw new IllegalArgumentException("遞增因子必須大於0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 將 key 中儲存的數字值遞減
     *
     * @param key   鍵
     * @param delta 要減少幾(小於0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta <= 0) {
            throw new IllegalArgumentException("遞減因子必須大於0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    /**
     * 將哈希表 key 中的字段 field 的值設為 value
     *
     * @param key   鍵
     * @param field 字段
     * @param value 值
     * @param time  時間(秒) 注意:如果已存在的hash表有時間,這里將會替換原有的時間
     * @return true 成功 false失敗
     */
    public boolean hset(String key, String field, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, field, value);
            if (time != CacheTime.CACHE_EXP_FOREVER) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 同時將多個 field-value (域-值)對設置到哈希表 key 中
     *
     * @param key  鍵
     * @param map  對應多個鍵值
     * @param time 時間(秒)
     * @return true成功 false失敗
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time != CacheTime.CACHE_EXP_FOREVER) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 刪除一個或多個哈希表字段
     *
     * @param key   鍵
     * @param field 字段 可以多個
     */
    public void hdel(String key, Object... field) {
        redisTemplate.opsForHash().delete(key, field);
    }

    /**
     * 獲取存儲在哈希表中指定字段的值
     *
     * @param key   鍵
     * @param field 字段
     * @return 值
     */
    public <T> T hget(String key, String field) {
        return (T) redisTemplate.opsForHash().get(key, field);
    }

    /**
     * 獲取在哈希表中指定 key 的所有字段和值
     *
     * @param key 鍵
     * @return 對應的多個鍵值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }


    /**
     * 查看哈希表 key 中,指定的字段是否存在
     *
     * @param key   鍵
     * @param field 字段
     * @return true 存在 false不存在
     */
    public boolean hexists(String key, String field) {
        return redisTemplate.opsForHash().hasKey(key, field);
    }

    /**
     * 獲取哈希表中字段的數量
     *
     * @param key 鍵
     * @return 字段數量
     */
    public long hlen(String key) {
        try {
            return redisTemplate.opsForHash().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 向集合添加一個或多個成員
     *
     * @param key    鍵
     * @param time   時間(秒)
     * @param values 成員 可以是多個
     * @return 成功個數
     */
    public long sadd(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time != CacheTime.CACHE_EXP_FOREVER) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 移除集合中一個或多個成員
     *
     * @param key    鍵
     * @param values 成員 可以是多個
     * @return 移除的個數
     */
    public long srem(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().remove(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 返回集合中的所有成員
     *
     * @param key 鍵
     * @return 成員列表
     */
    public <T> Set<T> smembers(String key) {
        try {
            return (Set<T>) redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 判斷 member 元素是否是集合 key 的成員
     *
     * @param key    鍵
     * @param member 成員
     * @return true 存在 false不存在
     */
    public boolean sismember(String key, Object member) {
        try {
            return redisTemplate.opsForSet().isMember(key, member);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 獲取集合的成員數
     *
     * @param key 鍵
     * @return 成員數
     */
    public long slen(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 在列表頭部添加一個值
     *
     * @param key   鍵
     * @param value 值
     * @param time  時間(秒)
     * @return boolean
     */
    public boolean lpush(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().leftPush(key, value);
            if (time != CacheTime.CACHE_EXP_FOREVER) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 在列表頭部添加多個值
     *
     * @param key    鍵
     * @param values 值
     * @param time   時間(秒)
     * @return boolean
     */
    public boolean lpush(String key, List<Object> values, long time) {
        try {
            redisTemplate.opsForList().leftPushAll(key, values);
            if (time != CacheTime.CACHE_EXP_FOREVER) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 在列表尾部添加一個值
     *
     * @param key   鍵
     * @param value 值
     * @param time  時間(秒)
     * @return boolean
     */
    public boolean rpush(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time != CacheTime.CACHE_EXP_FOREVER) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 在列表尾部添加多個值
     *
     * @param key    鍵
     * @param values 值
     * @param time   時間(秒)
     * @return boolean
     */
    public boolean rpush(String key, List<Object> values, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, values);
            if (time != CacheTime.CACHE_EXP_FOREVER) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除列表元素
     *
     * @param key   鍵
     * @param count 移除多少個
     * @param value 值
     * @return 移除的個數
     */
    public long lrem(String key, long count, Object value) {
        try {
            return redisTemplate.opsForList().remove(key, count, value);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 通過索引設置列表元素的值
     *
     * @param key   鍵
     * @param index 索引
     * @param value 值
     * @return boolean
     */
    public boolean lset(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 獲取列表指定范圍內的元素
     *
     * @param key   鍵
     * @param start 開始
     * @param end   結束 0 到 -1代表所有值
     * @return 元素列表
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> lrange(String key, long start, long end) {
        try {
            return (List<T>) redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 通過索引獲取列表中的元素
     *
     * @param key   鍵
     * @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數第二個元素,依次類推
     * @return
     */
    public Object lindex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 獲取列表長度
     *
     * @param key 鍵
     * @return 列表長度
     */
    public long llen(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 向有序集合添加一個成員,或者更新已存在成員的分數
     *
     * @param key    鍵
     * @param time   時間(秒)
     * @param member 成員
     * @param score  分數
     * @return
     */
    public boolean zadd(String key, long time, Object member, double score) {
        try {
            boolean ret = redisTemplate.opsForZSet().add(key, member, score);
            if (time != CacheTime.CACHE_EXP_FOREVER) {
                expire(key, time);
            }
            return ret;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除有序集合中的一個或多個成員
     *
     * @param key    鍵
     * @param values 值 可以是多個
     * @return 移除的個數
     */
    public long zrem(String key, Object... values) {
        try {
            return redisTemplate.opsForZSet().remove(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 通過索引區間返回有序集合成指定區間內的成員 分數從低到高
     *
     * @param key   鍵
     * @param start 開始
     * @param end   結束 0 到 -1代表所有值
     * @return 成員集合
     */
    public Set<Object> zrange(String key, long start, long end) {
        try {
            return redisTemplate.opsForZSet().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 通過索引區間返回有序集合成指定區間內的成員 分數從高到低
     *
     * @param key   鍵
     * @param start 開始
     * @param end   結束 0 到 -1代表所有值
     * @return 成員集合
     */
    public Set<Object> zrevrange(String key, long start, long end) {
        try {
            return redisTemplate.opsForZSet().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 返回有序集合中某個成員的分數值
     *
     * @param key    鍵
     * @param member 成員
     * @return 分數值
     */
    public double zscore(String key, Object member) {
        try {
            return redisTemplate.opsForZSet().score(key, member);
        } catch (Exception e) {
            e.printStackTrace();
            return 0.0;
        }
    }

    /**
     * 判斷有序集合中某個成員是否存在
     *
     * @param key    鍵
     * @param member 成員
     * @return true 存在 false不存在
     */
    public boolean zexist(String key, Object member) {
        try {
            return null != redisTemplate.opsForZSet().score(key, member);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 獲取有序集合的成員數
     *
     * @param key 鍵
     * @return 成員數
     */
    public long zlen(String key) {
        try {
            return redisTemplate.opsForZSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }
}

2.4 添加 Redis 常用配置項

在 application.properties 文件中的添加 Redis 相關的配置項:

# 數據庫索引(默認為0)
spring.redis.database = 1
# 服務器地址
spring.redis.host = 127.0.0.1
# 服務器連接端口
spring.redis.port = 6379
# 服務器連接密碼(默認為空)
spring.redis.password =
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait = -1
# 連接超時時間(毫秒)
spring.redis.timeout = 3000 
# 連接池最大連接數
spring.redis.jedis.pool.max-active = 8
# 連接池中的最大空閑連接
spring.redis.jedis.pool.max-idle = 8
# 連接池中的最小空閑連接
spring.redis.jedis.pool.min-idle = 1

2.5 Redis 緩存測試

① 首先在 DemoService 中注入 RedisClient ,修改 test 方法將 user 對象以 user:1 為鍵存放到 Redis 中。

Redis 開發規范:https://yq.aliyun.com/articles/531067

package com.example.demo.biz.service.impl;

import com.example.demo.biz.service.DemoService;
import com.example.demo.common.redis.CacheTime;
import com.example.demo.common.redis.RedisClient;
import com.example.demo.dao.entity.UserDO;
import com.example.demo.dao.mapper.business.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author linjian
 * @date 2019/1/15
 */
@Service
public class DemoServiceImpl implements DemoService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisClient redisClient;

    @Override
    public String test() {
        UserDO user = userMapper.selectById(1);
        redisClient.set("user:1", user, CacheTime.CACHE_EXP_FIVE_MINUTES);
        return user.toString();
    }
}

② 之后使用 Redis Desktop Manager 客戶端連接 Redis 服務器,選擇數據庫「 1 」,查看剛存放的緩存。
SpringBoot_4_1.png


三、結語

至此 Spring Boot 集成 Redis 的具體步驟介紹完畢,我們自定義了 Redis 的序列化方式,並通過一個簡單的例子測試了 Redis 的可用性,相關代碼已同步至 GitHub 。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM