springboo2.x 集成 redis Lettuce连接池

在spring boot2之后,对redis连接的支持,默认就采用了lettuce 这就一定程度说明了lettuce 和Jedis的优劣。

1.引入依赖

        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
        
            org.apache.commons
            commons-pool2
        

2.application.yml配置一下redis服务器的地址

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    # 密码 没有则不填
    password: 123456
    # 连接超时时间
    timeout: 10000s
    #lettuce配置
    lettuce:
      pool:
        # 最大活跃链接数 默认8
        max-active: 8
        # 最大空闲连接数 默认8
        max-idle: 8
        # 最小空闲连接数 默认0
        min-idle: 0
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1

 

3.redis配置

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.CacheResolver;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author shuzhuo
 * @date 2019/7/30
 */
@Configuration
@Slf4j
public class RedisConfig extends CachingConfigurerSupport {

    @Override
    public CacheResolver cacheResolver() {
        return super.cacheResolver();
    }

    /**
     * 设置自动key的生成规则
     * @return
     */
    @Override
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName());
            sb.append(":");
            sb.append(method.getName());
            for (Object obj : params) {
                sb.append(":" + String.valueOf(obj));
            }
            String rsToUse = String.valueOf(sb);
            log.info("自动生成Redis Key -> [{}]", rsToUse);
            return rsToUse;
        };
    }

    /**
     * 打印错误日志
     * @return
     */
    @Override
    public CacheErrorHandler errorHandler() {
        log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
        CacheErrorHandler cacheErrorHandler = new CacheErrorHandler() {
            @Override
            public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
                log.error("Redis occur handleCacheGetError:key -> [{}]", key, e);
            }

            @Override
            public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
                log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e);
            }

            @Override
            public void handleCacheEvictError(RuntimeException e, Cache cache, Object key)    {
                log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e);
            }

            @Override
            public void handleCacheClearError(RuntimeException e, Cache cache) {
                log.error("Redis occur handleCacheClearError:", e);
            }
        };
        return cacheErrorHandler;
    }

    /**
     * 配置自定义redisTemplate
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        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);
        // 配置redisTemplate
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer); // key序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // value序列化
        redisTemplate.setHashKeySerializer(stringSerializer); // Hash key序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); // Hash value序列化
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer redisSerializer = new StringRedisSerializer();
        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);


        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(10))
                .disableCachingNullValues()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
        //定义 key,这里随便定义3个
        String keyName1="keyName1";
        String keyName2="keyName2";
        String keyName3="keyName3";
        // 初始化的缓存空间set集合
        Set cacheNames =  new HashSet<>();
        cacheNames.add(keyName1);
        cacheNames.add(keyName2);
        cacheNames.add(keyName3);

        // 对每个缓存空间应用不同的配置
        Map configMap = new HashMap<>();
        configMap.put(keyName1, config);
        configMap.put(keyName2, config.entryTtl(Duration.ofSeconds(20)));
        configMap.put(keyName3, config.entryTtl(Duration.ZERO));

        RedisCacheConfiguration defaultConfig = config.entryTtl(Duration.ofSeconds(30));
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)     // 使用自定义的缓存配置初始化一个cacheManager
                .initialCacheNames(cacheNames)  // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
                .withInitialCacheConfigurations(configMap)
                .cacheDefaults(defaultConfig) //默认配置 //@CachePut 创建的cache 使用默认配置
                .build();
        log.info("cacheManager init success");
        return cacheManager;
    }



}

 

4.测试

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.concurrent.TimeUnit;

/**
 * @author shuzhuo
 * @date 2019/7/30 15:58
 */
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class RedisTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CacheManager cacheManager;

    @Test
    public void cacheManagerTest() {
        //10s
        Cache cache = cacheManager.getCache("keyName1");
        if (cache!=null){
            cache.put("key1","key1-value");
        }
        //20s
        Cache cache2 = cacheManager.getCache("keyName2");
        if (cache2!=null){
            cache2.put("key2","key2-value");
        }
        //永久
        Cache cache3 = cacheManager.getCache("keyName3");
        if (cache3!=null){
            cache3.put("key3","key3-value");
        }
//        @CachePut 的在接口测试,这里不做测试

    }

    @Test
    public void redisTest() {
        // redis存储数据
        String key = "shuzhuo-key";
        redisTemplate.opsForValue().set(key, "shuzhuo-value", 10, TimeUnit.SECONDS);
        // 获取数据
        String value = (String) redisTemplate.opsForValue().get(key);
        System.out.println("获取缓存中key为" + key + "的值为:" + value);

        //SySUser 对象这里不写创建
        SySUser user = new SySUser();
        user.setUsername("shuzhuo");
        user.setId(1);
        String userKey = "shuzhuo";
        redisTemplate.opsForValue().set(userKey, user, 10, TimeUnit.SECONDS);

        SySUser newUser = (SySUser) redisTemplate.opsForValue().get(userKey);
        System.out.println("获取缓存中key为" + userKey + "的值为:" + newUser);
    }


}

客户端连接查看数据

你可能感兴趣的:(redis)