Spring Data Redis - Spring Boot 168 EP 17

Spring Data Redis – Spring Boot 168 EP 17

支援連線池管理,封裝了客戶端 API,提供 Operations、BoundKeyOperations 等操作, EP 17 增加了相依套件及範例,並透過 JUnit 5 單元測試來驗證產出結果。

前言

Redis 是一個高性能鍵值儲存的記憶體型的資料庫,支援資料的持久化,可以將記憶體的資料儲存在磁碟,重啟後可以再重新載入,同時提供 List 、 Set 、 Zset 、 Hash 等資料結構儲存,也支援資料備份,即 Master-Slave 主從模式的資料備份。

Spring Data Redis

檔案目錄

./
   +- build.gradle
       +- src
           +- main
               +- resources
               |   +- application.properties
               +- java
               |   +- org
               |       +- ruoxue
               |           +- spring_boot_168
               |               +- config
               |                   +- RedisConfig.java   

Gradle

build.gradle

增加 Spring Boot Starter Data Redis 。

增加 Commons Pool2 。

修改完後,點右鍵,Gradle -> Refresh Gradle Project 。

buildscript {
	group 'org.ruoxue.spring-boot-168'
	version = '0.0.1-SNAPSHOT'
	ext {
		springBootVersion = '2.1.7.RELEASE'
	}
}

dependencies {
	implementation "org.springframework.boot:spring-boot-starter-data-redis:${springBootVersion}"
	implementation 'org.apache.commons:commons-pool2:2.6.0'
}

設定

application.properties

增加 Redis 設定。

spring.data.redis.repositories.enabled=true
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.jedis.pool.max-active=100
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-wait=60000ms
spring.redis.jedis.pool.min-idle=1
spring.redis.lettuce.pool.max-active=100
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-wait=60000ms
spring.redis.lettuce.pool.min-idle=1
spring.redis.lettuce.shutdown-timeout=60000ms
spring.redis.password=
spring.redis.port=6379
spring.redis.ssl=false
spring.redis.timeout=60000

RedisConfig.java

新增檔案。

package org.ruoxue.spring_boot_168.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
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.StringRedisSerializer;

import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import java.time.Duration;

@Configuration
public class RedisConfig {

	@Autowired
	private RedisConnectionFactory redisConnectionFactory;

	@Bean
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public RedisTemplate<String, Object> redisTemplate() {
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
		redisTemplate.setConnectionFactory(redisConnectionFactory);
		Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
		StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
		redisTemplate.setKeySerializer(stringRedisSerializer);
		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
		redisTemplate.setHashKeySerializer(stringRedisSerializer);
		redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
		redisTemplate.setEnableDefaultSerializer(true);
		redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
		return redisTemplate;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Bean
	public CacheManager cacheManager(RedisConnectionFactory factory) {
		StringRedisSerializer stringRedisSerializer = 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);
		Duration duration = Duration.ofHours(8L);
		RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(duration)
				.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))
				.serializeValuesWith(
						RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
				.disableCachingNullValues();
		RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();
		return cacheManager;
	}
}

測試

RedisConfigTest.java

新增單元測試,驗證是否符合預期 。

package org.ruoxue.spring_boot_168.config;

import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.ruoxue.spring_boot_168.Application;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Application.class)
public class RedisConfigTest {

	@Autowired
	private RedisConfig config;

	@Test
	public void config() {
		System.out.println(config);
		assertNotNull(config);
	}
}

config

測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console 。

org.ruoxue.spring_boot_168.config$$EnhancerBySpringCGLIB$$5d2a8a72@2aac6fa7

心得分享

實現連線池管理,設定連線池最大與最小連線數限制,讓連線更有效率,節省系統資源的耗用,並提供 RedisTemplate,對 Redis 進行各種操作,支援所有原生的 API。

發佈留言