1、需求背景
?項目需要提供一個管理界面給內部人員操作用戶信息,需要在修改用戶信息后刪除用戶的redis緩存。用戶所在的區域不同,其redis服務地址也不相同,因此需要管理多個redis連接,且redis要求以集群方式并支持ssl進行連接。
2、實現方案
?為每個區域定義一個regionId,用來關聯不同區域的redis連接信息,將redis連接信息存于數據庫中。采用工具類的方式,構建RedisTemplate對象存于以Map形式存于工具類中的靜態變量當中,key為regionId,value為RedisTemplate。每個RedisTemplate構建時機為第一次需要用到它時。
3、具體實現
1、首先是存儲redis信息的實體類
public class RedisInfo {private String regionId;private String ip;private int port;private String pwd;// 是否使用sslprivate boolean ssl;// 超時時間private long timeout;
}
2、其次是工具類的實現
public class RedisManage {private static Map<String, RedisTemplate<String, Object>> redisTemplateMap = new HashMap<>();/*** 獲取RedisTemplate方法* @param redisInfo 數據庫連接信息* @return*/public static RedisTemplate<String, Object> getRedisTemplate(RedisInfo redisInfo) {// 首先從map中獲取RedisTemplate<String, Object> redisTemplate = redisTemplateMap.get(redisInfo.getRegionId());// 獲取不到就構建一個并存入redisif (redisTemplate == null) {// redis連接配置RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();redisStandaloneConfiguration.setHostName(redisInfo.getIp());redisStandaloneConfiguration.setPort(redisInfo.getPort());redisStandaloneConfiguration.setPassword(RedisPassword.of(redisInfo.getPwd()));// 創建 LettuceClientConfiguration,用于構建LettuceConnectionFactoryLettuceClientConfiguration.LettuceClientConfigurationBuilder builder = LettuceClientConfiguration.builder().commandTimeout(Duration.ofMillis(redisInfo.getTimeout())).shutdownTimeout(Duration.ofMillis(redisInfo.getTimeout()));// 根據需要啟用sslif (redisInfo.isSsl()) {builder.useSsl();}// 創建 LettuceConnectionFactory,集群連接的關鍵LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, builder.build());// 重要,調用afterPropertiesSet才能正常使用factory.afterPropertiesSet();redisTemplate = new RedisTemplate();redisTemplate.setConnectionFactory(factory);// 將對象屬性名序列化成string類型的key,并將string類型的key反序列化成屬性名StringRedisSerializer keySerializer = new StringRedisSerializer();// 數據綁定工具,操作redis時需要對key和value進行序列化和反序列化,這個對象可以設置規范ObjectMapper mapper = new ObjectMapper();// 反序列化時遇到未知屬性不拋出異常mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);// 序列化空bean時不拋出異常mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);// 反序列化時對象的成員變量與緩存中的對象類型對不上或代碼中不存在該類時,不拋出異常mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);// 序列化時間字段時,以文本形式序列序列化而非時間戳mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);// 支持Java8的日期類型,如LocalDate、LocalTime、LocalDateTime等mapper.registerModule(new JavaTimeModule());// 序列化時保留對象類型信息mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);// 序列化和反序列化工具,使用jackson庫將對象序列化成json字符串,并將json字符串反序列化成對象,應用了上面ObjectMapper的各項規范RedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer(mapper);redisTemplate.setKeySerializer(keySerializer);redisTemplate.setValueSerializer((RedisSerializer)valueSerializer);redisTemplate.setHashKeySerializer(keySerializer);redisTemplate.setHashValueSerializer((RedisSerializer)valueSerializer);// 重要,非托管Spring容器構建的RedisTemplate需要調用afterPropertiesSet()方法redisTemplate.afterPropertiesSet();redisTemplateMap.put(redisInfo.getRegionId(), redisTemplate);}return redisTemplate;}}