欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot混合使用StringRedisTemplate和RedisTemplate的坑及解決

 更新時(shí)間:2023年12月20日 16:01:18   作者:程序新視界  
這篇文章主要介紹了SpringBoot混合使用StringRedisTemplate和RedisTemplate的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

但在實(shí)踐中,有朋友遇到這樣的問題,就是存儲(chǔ)到Redis數(shù)據(jù)取不到值。

兩種Template的源碼分析

這是為什么呢?是因?yàn)樗瑫r(shí)使用了StringRedisTemplate和RedisTemplate在Redis中存儲(chǔ)和讀取數(shù)據(jù)。

它們最重要的一個(gè)區(qū)別就是默認(rèn)采用的序列化方式不同(在課程中已經(jīng)講到)。

這里我們?cè)賮砘仡櫼幌孪嚓P(guān)源碼,StringRedisTemplate的部分源碼如下:

public class StringRedisTemplate extends RedisTemplate<String, String> {

	/**
	 * Constructs a new <code>StringRedisTemplate</code> instance. {@link #setConnectionFactory(RedisConnectionFactory)}
	 * and {@link #afterPropertiesSet()} still need to be called.
	 */
	public StringRedisTemplate() {
		setKeySerializer(RedisSerializer.string());
		setValueSerializer(RedisSerializer.string());
		setHashKeySerializer(RedisSerializer.string());
		setHashValueSerializer(RedisSerializer.string());
	}
    
}

通過該源碼我們可以看到StringRedisTemplate采用的是RedisSerializer.string()來序列化Redis中存儲(chǔ)數(shù)據(jù)的Key的。

下面再來看看RedisTemplate中默認(rèn)采用什么形式來序列化對(duì)應(yīng)的Key。

public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
    // 省略其他源碼
	private @Nullable RedisSerializer<?> defaultSerializer;
	private @Nullable ClassLoader classLoader;

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.redis.core.RedisAccessor#afterPropertiesSet()
	 */
	@Override
	public void afterPropertiesSet() {

		super.afterPropertiesSet();

		boolean defaultUsed = false;

		if (defaultSerializer == null) {

			defaultSerializer = new JdkSerializationRedisSerializer(
					classLoader != null ? classLoader : this.getClass().getClassLoader());
		}

		if (enableDefaultSerializer) {

			if (keySerializer == null) {
				keySerializer = defaultSerializer;
				defaultUsed = true;
			}
			// 省略其他源碼
		}

		if (enableDefaultSerializer && defaultUsed) {
			Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
		}

		if (scriptExecutor == null) {
			this.scriptExecutor = new DefaultScriptExecutor<>(this);
		}

		initialized = true;
	}
	// 省略其他源碼
    
}

我們可以看到RedisTemplate使用的序列化類為defaultSerializer,默認(rèn)情況下為JdkSerializationRedisSerializer。

如果未指定Key的序列化類,keySerializer與defaultSerializer采用相同的序列化類。

通過上述兩個(gè)Template的分析我們就可以看出它們?cè)赗edis存儲(chǔ)的Key,采用了不同的序列化方法。

而且JdkSerializationRedisSerializer序列化時(shí)會(huì)在Key的前面添加一些特殊字符。

還原測試

下面先看一個(gè)單元測試:

@Slf4j
@SpringBootTest
class RedisDifferentTemplateTest {
	@Resource
	private RedisTemplate<String, Object> redisTemplate;

	@Resource
	private StringRedisTemplate stringRedisTemplate;

	@Test
	void testSimple() {
		redisTemplate.opsForValue().set("myWeb", "www.choupangxia.com");
		Assertions.assertEquals("www.choupangxia.com", redisTemplate.opsForValue().get("myWeb"));

		Assertions.assertEquals("www.choupangxia.com",stringRedisTemplate.opsForValue().get("myWeb"));
	}
}

在上述方法中先通過redisTemplate存儲(chǔ)一個(gè)key為myWeb的數(shù)據(jù)到Redis中,隨后通過redisTemplate獲取并判斷斷言,可以成功通過。

但隨后通過stringRedisTemplate獲取同樣的key的值,則拋出異常,異常信息如下:

org.opentest4j.AssertionFailedError: 

Expected :www.choupangxia.com

Actual   :null

 <Click to see difference>

也就是說獲取的結(jié)果為null。

那么,我們?cè)偻ㄟ^Redis客戶端看一下兩種形式存儲(chǔ)到redis中key的值的情況。

image

我們可以看到通過StringRedisTemplate存儲(chǔ)的數(shù)據(jù)Key為“myWeb”,而RedisTemplate存儲(chǔ)的Key為“\xAC\xED\x00\x05t\x00\x05myWeb”,這也就是為什么默認(rèn)情況下兩者存儲(chǔ)的數(shù)據(jù)沒辦法混合使用了。

解決方案

那么,如果在生產(chǎn)環(huán)境中想通用StringRedisTemplate和RedisTemplate進(jìn)行字符串的處理該怎么辦?

此時(shí)就需要指定統(tǒng)一的Key的序列化處理類,比如在RedisTemplate序列化時(shí)指定與StringRedisTemplate相同的類。

在上述單元測試中添加如下方法:

@BeforeEach
void init() {
	redisTemplate.setKeySerializer(RedisSerializer.string());
}

也就是設(shè)置RedisTemplate也使用RedisSerializer.string()來序列化Key。注意此處使用的是Junit5。

這樣就解決問題了嗎?沒有。因?yàn)镽edisTemplate的Value也是采用默認(rèn)的序列化類,也要進(jìn)行統(tǒng)一修改。

因此上面的方法變成如下:

@BeforeEach
void init() {
	redisTemplate.setKeySerializer(RedisSerializer.string());
	redisTemplate.setValueSerializer(RedisSerializer.string());
}

總結(jié)

經(jīng)過上述步驟,關(guān)于SpringBoot中混合使用StringRedisTemplate和RedisTemplate的坑已經(jīng)填平了。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • SpringBoot在idea中的 .idea和 .iml文件的作用

    SpringBoot在idea中的 .idea和 .iml文件的作用

    本文主要介紹了SpringBoot在idea中的 .idea和 .iml文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • InterProcessMutex實(shí)現(xiàn)zookeeper分布式鎖原理

    InterProcessMutex實(shí)現(xiàn)zookeeper分布式鎖原理

    本文主要介紹了InterProcessMutex實(shí)現(xiàn)zookeeper分布式鎖原理,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • JDK安裝方法和Linux常見設(shè)置詳細(xì)版教程

    JDK安裝方法和Linux常見設(shè)置詳細(xì)版教程

    這篇文章主要給大家介紹了關(guān)于JDK安裝方法和Linux常見設(shè)置的相關(guān)資料,文章詳細(xì)介紹了如何在Linux系統(tǒng)中設(shè)置靜態(tài)IP、用戶名和主機(jī)名,配置防火墻,安裝JDK以及如何創(chuàng)建系統(tǒng)快照,需要的朋友可以參考下
    2024-11-11
  • SpringBoot配置文件的加載位置實(shí)例詳解

    SpringBoot配置文件的加載位置實(shí)例詳解

    springboot采納了建立生產(chǎn)就緒spring應(yīng)用程序的觀點(diǎn)。 在一些特殊的情況下,我們需要做修改一些配置,或者需要有自己的配置屬性。接下來通過本文給大家介紹SpringBoot配置文件的加載位置,感興趣的朋友一起看看吧
    2018-09-09
  • java虛擬機(jī)學(xué)習(xí)筆記進(jìn)階篇

    java虛擬機(jī)學(xué)習(xí)筆記進(jìn)階篇

    在本篇內(nèi)容里小編給大家分享了關(guān)于java虛擬機(jī)學(xué)習(xí)筆記的進(jìn)階內(nèi)容,需要的朋友們跟著學(xué)習(xí)下。
    2019-06-06
  • Java Netty實(shí)現(xiàn)心跳機(jī)制過程解析

    Java Netty實(shí)現(xiàn)心跳機(jī)制過程解析

    這篇文章主要介紹了Java Netty實(shí)現(xiàn)心跳機(jī)制過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Spring整合mybatis實(shí)現(xiàn)過程詳解

    Spring整合mybatis實(shí)現(xiàn)過程詳解

    這篇文章主要介紹了Spring整合mybatis實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • SpringBoot調(diào)用WebService接口的實(shí)現(xiàn)示例

    SpringBoot調(diào)用WebService接口的實(shí)現(xiàn)示例

    本文主要介紹了SpringBoot調(diào)用WebService接口的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • Java快速排序及求數(shù)組中第k小的值解析

    Java快速排序及求數(shù)組中第k小的值解析

    這篇文章主要介紹了Java快速排序及求數(shù)組中第k小的值解析,選一個(gè)中間值,把數(shù)組中比它小的元素放到左邊,比它大的元素放到右邊,這時(shí)形成三個(gè)子數(shù)組,分別是中間值,比它大的數(shù)和比它小的數(shù),然后對(duì)前后兩個(gè)數(shù)組進(jìn)行遞歸,需要的朋友可以參考下
    2023-11-11
  • java中staticclass靜態(tài)類詳解

    java中staticclass靜態(tài)類詳解

    這篇文章主要介紹了java中staticclass靜態(tài)類詳解,具有一定借鑒價(jià)值,需要的朋友可以了解下。
    2017-12-12

最新評(píng)論