SpringBoot2.x使用redis(Lettuce)和RedisTemplate

爲什麼使用Lettuce:

Spring-data-redis提供了在spring應用中通過簡單的配置訪問redis服務,對reids底層開發包(Jedis,  JRedis, and RJC)進行了高度封裝

RedisTemplate提供了redis各種操作、異常處理及序列化,支持發佈訂閱,並對spring 3.1 cache進行了實現。

特徵https://spring.io/projects/spring-data-redis

  • 連接包是跨多個Redis驅動程序(LettuceJedis)的底層抽象。

  • RedisTemplate提供了用於執行各種Redis操作,異常轉換和序列化支持的高級抽象。

  • Pubsub支持(例如,消息驅動的POJO的MessageListenerContainer)。

  • Redis SentinelRedis Cluster支持。

  • JDK,String,JSON和Spring Object / XML映射序列化器

  • Redis之上的JDK Collection實現。

  • 原子計數器支持類。

  • 排序和流水線功能。

  • Spring 3.1緩存抽象的Redis 實現

Spring Data Redis(SDR)框架通過Spring出色的基礎架構支持消除了與存儲庫交互所需的冗餘任務和樣板代碼,從而簡化了編寫使用Redis鍵值存儲庫的Spring應用程序的過程。 

redis序列化存儲的問題:

編寫緩存配置類RedisConfig用於調優緩存默認配置,RedisTemplate<String, Object>的類型兼容性更高

大家可以看到在redisTemplate()這個方法中用JacksonJsonRedisSerializer更換掉了Redis默認的序列化方    式:JdkSerializationRedisSerializer

spring-data-redis中序列化類有以下幾個:

GenericToStringSerializer可以將任何對象泛化爲字符創並序列化

Jackson2JsonRedisSerializer序列化Object對象爲json字符創(與JacksonJsonRedisSerializer相同)    

JdkSerializationRedisSerializer序列化java 對象 StringRedisSerializer:簡單的字符串序列化

JdkSerializationRedisSerializer序列化被序列化對象必須實現Serializable接口,被序列化除屬性內容還有其他內容,長度長且不易閱讀,默認就是採用這種序列化方式

存儲內容如下:

"\xac\xed\x00\x05sr\x00!com.oreilly.springdata.redis.User\xb1\x1c

\n\xcd\xed%\xd8\x02\x00\x02I\x00\x03ageL\x00\buserNamet\x00\x12Ljava/lang/String;xp\x00\x00\x00\ x14t\x00\x05user1"

JacksonJsonRedisSerializer序列化,被序列化對象不需要實現Serializable接口,被序列化的結果清晰,容易閱讀,而且存儲字節少,速度快

存儲內容如下:

"{"userName":"guoweixin","age":20}"

StringRedisSerializer序列化

一般如果keyvalue都是string字符串的話,就是用這個就可以了

項目目錄:

 

一、pom文件,引入依賴

        <!--Spring Data Redis 默認是lettuce客戶端-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--redis依賴pool連接池這個jar包-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.7.0</version>
        </dependency>

配置文件:application.yml

server:
   port: 8889

#redis
spring:
  redis:
    port: 6379
    password: Xxf159357!_
    host: 182.92.236.141
    lettuce:
      pool:
        max-active: 100 # 連接池最大連接數(使用負值表示沒有限制) 太小可能出現connection.PoolExcelption
        max-idle: 8 # 連接池中的最大空閒連接
        min-idle: 0 # 連接池中的最小空閒連接
        max-wait: 1000 # 連接池最大阻塞等待時間(使用負值表示沒有限制)
      shutdown-timeout: 100	# 關閉超時時間
#log 出現<font color=red>CONDITIONS EVALUATION REPORT</font>
#<font color=red>java.lang.IllegalStateException: Failed to load ApplicationContext</font>釋放下面代碼
#logging.level.org.springframework.boot.autoconfigure: error
#logging:
  #level: info

 二、RedisConfig類

package com.xxf.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;

/**
 * @Author:xuefengxia
 * @Date:2020/6/18
 * @Description:
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * 自定義緩存key的生成策略。默認的生成策略是看不懂的(亂碼內容)
     * 通過Spring 的依賴注入特性進行自定義的配置注入並且此類是一個配置類可以更多程度的自定義配置
     * @return
     */
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {

            @Override
            public Object generate(Object target, Method method, Object... 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();
            }
        };
    }

    /**
     * 緩存配置管理器
     */
    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory factory) {
        //以鎖寫入的方式創建RedisCacheWriter對象
        RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
        //創建默認緩存配置對象
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        RedisCacheManager cacheManager = new RedisCacheManager(writer, config);
        return cacheManager;
    }


    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        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();
        // 在使用註解@Bean返回RedisTemplate的時候,同時配置hashKey與hashValue的序列化方式。
        // key採用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // value 序 列 化 方 式 採 用 jackson
        //使用它操作普通字符串,會出現Could not read JSON  template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(stringRedisSerializer);
        // hash的key也採用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // hash的value序列化方式採用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

三、實例RedisServImpl

package com.xxf.service;

import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @Author:xuefeng
 * @Date:2020/6/18
 * @Description:
 */
@Service
@Log
public class RedisServiceImpl {

@Autowired
private RedisTemplate<String,Object> redisTemplate;


    /**
     *普通緩存放入
     *@param key 鍵
     *@return true成功 false失敗
     */
    public String getString(String key) {
        if(redisTemplate.hasKey(key)) {
            log.info("Redis中查詢");
            redisTemplate.opsForValue().set("jsonStr","{'userName':'xxf','age':20}");
            System.out.println(redisTemplate.opsForValue().get(key));
            return (String) redisTemplate.opsForValue().get(key);
        }else{
            String val="xxf";
            redisTemplate.opsForValue().set(key, val);
            log.info("數據庫中查詢的");
            return	val;
        }
    }

    /**
     *普通緩存放入
     *@param key 鍵
     *@param value 值
     *@param expireTime 超時時間(秒)
     *@return true成功 false失敗
     */
    public Boolean set(String key, Object value, int expireTime) {
        try {
            redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

四、測試類

package com.xxf.lettuce;

import com.xxf.service.RedisServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @Author:xuefeng
 * @Date:2020/6/18
 * @Description:
 */
@SpringBootTest
class TestRedisTemplate {
    @Autowired
    private RedisServiceImpl redisService;
    @Test
    public void testGetKey() {
        redisService.getString("jsonStr");
    }
    @Test
    public void testSetKey() {
        redisService.set("xxf","黎明的光與影",5000);
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章