1. 程式人生 > >SpringBoot2.0整合Redis

SpringBoot2.0整合Redis

【1】pom依賴

新增redis依賴如下:

<!--整合redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <!-- 1.5的版本預設採用的連線池技術是jedis  2.0以上版本預設連線池是lettuce,
    在這裡採用jedis,所以需要排除lettuce的jar -->
    <exclusions
>
<exclusion> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </exclusion> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId
>
</exclusion> </exclusions> </dependency> <!-- 新增jedis客戶端 --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <!--spring2.0整合redis所需common-pool2 必須加上,jedis依賴此 --> <!-- spring boot 2.0 的操作手冊有標註 地址是:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/-->
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.5.0</version> <!--<version>2.4.2</version>--> </dependency>

【2】yml配置

yml中對redis配置如下:

spring:
    redis:
      host: 127.0.0.1
      port: 6379
      password: admin
      jedis:
        pool:
          #最大連線數
          max-active: 1024
          #最大阻塞等待時間(負數表示沒限制)
          max-wait: 20000
          #最大空閒
          max-idle: 200
          #最小空閒
          min-idle: 10
      #連線超時時間
      timeout: 10000

注意,與SpringBoot1.X整合Redis配置不同。

【3】Redis配置類

MyRedisConfig如下:

@Configuration// 必須加,使配置生效
@EnableCaching
public class MyRedisConfig extends CachingConfigurerSupport {
    /**
     * Logger
     */
    private static final Logger log = LoggerFactory.getLogger(MyRedisConfig.class);


    @Autowired
    private JedisConnectionFactory jedisConnectionFactory;


    @Bean
    @Override
    public CacheManager cacheManager() {
        // 初始化快取管理器,在這裡我們可以快取的整體過期時間什麼的,我這裡預設沒有配置
        log.info("初始化 -> [{}]", "CacheManager RedisCacheManager Start");
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
                .RedisCacheManagerBuilder
                .fromConnectionFactory(jedisConnectionFactory);
        return builder.build();
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory ) {
        //設定序列化
        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<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory);
        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;
    }

    @Override
    @Bean
    public CacheErrorHandler errorHandler() {
        // 異常處理,當Redis發生異常時,列印日誌,但是程式正常走
        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,替換了預設的jdk 序列化機制,使存入redis中的value json化,體驗更友好。

【4】測試例項

測試value為String和Object的存取。

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    RedisTemplate redisTemplate;

    @Test
    public void testRedis(){
        // 測試redis
        if(stringRedisTemplate.hasKey("hello")){
            String hello = stringRedisTemplate.opsForValue().get("hello");
            System.out.println("從redis中獲取 key-hello--value : "+hello);
            stringRedisTemplate.opsForValue().set("jane","is a boy");

        }
        SysApk sysApk = sysApkMapper.selectByPrimaryKey(1L);
        redisTemplate.opsForValue().set("sysApk",sysApk);
        SysApk sysApk2 = (SysApk) redisTemplate.opsForValue().get("sysApk");
        System.out.println(sysApk2);
    }

【Tips】

需要注意的是Redis中value是不允許為null或者儘量不要為null的。

使用Jedis客戶端直接set鍵值的時候,如果value為null,會拋異常:

這裡寫圖片描述

在SpringBoot下使用StringRedisTemplate或者RedisTemplate進行鍵值set時,如果value為null,會將其序列化為,存入redis不會丟擲異常。

redisTemplate.opsForValue().set("sysApk",null);

System.out.println(redisTemplate.opsForValue().get("sysApk"));
//列印結果 :null

// 客戶端直接獲取
127.0.0.1:6379> get sysApk
""

不過還是建議redis中value值一般不要為null。

參考部落格: