最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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的前面添加一些特殊字符。

還原測(cè)試

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

@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相同的類。

在上述單元測(cè)試中添加如下方法:

@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)文章

  • MyBatis框架搭建時(shí)依賴包引入異常的問題解決

    MyBatis框架搭建時(shí)依賴包引入異常的問題解決

    在使用IDEA環(huán)境搭建MyBatis框架時(shí),可能會(huì)因?yàn)橐蕾嚢姹具^低導(dǎo)致兼容性問題,本文就來介紹一下MyBatis框架搭建時(shí)依賴包引入異常的問題解決,感興趣的可以來了解一下
    2024-10-10
  • Spring?Boot集成Elasticsearch全過程

    Spring?Boot集成Elasticsearch全過程

    這篇文章主要介紹了Spring?Boot集成Elasticsearch全過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-07-07
  • Java高級(jí)架構(gòu)之FastDFS分布式文件集群詳解

    Java高級(jí)架構(gòu)之FastDFS分布式文件集群詳解

    這篇文章主要介紹了Java高級(jí)架構(gòu)之FastDFS分布式文件集群詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-04-04
  • 詳解mall整合SpringBoot+MyBatis搭建基本骨架

    詳解mall整合SpringBoot+MyBatis搭建基本骨架

    這篇文章主要介紹了詳解mall整合SpringBoot+MyBatis搭建基本骨架,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java責(zé)任鏈模式詳解

    Java責(zé)任鏈模式詳解

    責(zé)任鏈模式(Chain?of?Responsibility?Pattern)是一種行為型設(shè)計(jì)模式,它用于將請(qǐng)求的發(fā)送者和接收者解耦,使得多個(gè)對(duì)象都有機(jī)會(huì)處理這個(gè)請(qǐng)求,本文將詳細(xì)介紹?Java?中的責(zé)任鏈模式,包括其概念、結(jié)構(gòu)、實(shí)現(xiàn)方式以及應(yīng)用案例等,需要的朋友可以參考下
    2023-05-05
  • Eclipse開發(fā)JavaWeb項(xiàng)目配置Tomcat的方法步驟

    Eclipse開發(fā)JavaWeb項(xiàng)目配置Tomcat的方法步驟

    本文主要介紹了Eclipse開發(fā)JavaWeb項(xiàng)目配置Tomcat的方法步驟,首先介紹eclipse開發(fā)JavaWeb項(xiàng)目需要配置的相關(guān)環(huán)境,使用tomcat軟件在本地搭建服務(wù)器,然后再在eclipse環(huán)境下配置tomcat,感興趣的可以了解一下
    2021-08-08
  • SpringBoot集成gRPC微服務(wù)工程搭建實(shí)踐的方法

    SpringBoot集成gRPC微服務(wù)工程搭建實(shí)踐的方法

    這篇文章主要介紹了SpringBoot集成gRPC微服務(wù)工程搭建實(shí)踐的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • 詳解JVM系列之對(duì)象的鎖狀態(tài)和同步

    詳解JVM系列之對(duì)象的鎖狀態(tài)和同步

    鎖和同步是java多線程編程中非常常見的使用場(chǎng)景。為了鎖定多線程共享的對(duì)象,Java需要提供一定的機(jī)制來實(shí)現(xiàn)共享對(duì)象的鎖定。當(dāng)?shù)诙€(gè)線程進(jìn)入同一個(gè)區(qū)域的時(shí)候,必須等待第一個(gè)線程解鎖該對(duì)象。JVM是怎么做到的呢?快來一起看看吧。
    2021-06-06
  • Spring?Boot?3.1中整合Spring?Security和Keycloak的方法

    Spring?Boot?3.1中整合Spring?Security和Keycloak的方法

    本文介紹在最新的SpringBoot3.1版本之下,如何將Keycloak和Spring?Security一起跑起來,文中結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-06-06
  • Java實(shí)現(xiàn)分布式鎖的3種方法總結(jié)

    Java實(shí)現(xiàn)分布式鎖的3種方法總結(jié)

    分布式鎖是一種用于保證分布式系統(tǒng)中多個(gè)進(jìn)程或線程同步訪問共享資源的技術(shù),同時(shí)它又是面試中的常見問題,所以我們本文就重點(diǎn)來看分布式鎖的具體實(shí)現(xiàn),希望對(duì)大家有所幫助
    2023-09-09

最新評(píng)論

额济纳旗| 东明县| 富宁县| 孝昌县| 德昌县| 石泉县| 达州市| 乳源| 安泽县| 长沙市| 渑池县| 浦北县| 淮阳县| 南澳县| 方城县| 平江县| 缙云县| 铁岭县| 吉安县| 三江| 保靖县| 白山市| 兴安盟| 林周县| 庐江县| 周至县| 乐昌市| 平泉县| 武鸣县| 安庆市| 墨竹工卡县| 乐清市| 松潘县| 马鞍山市| 陆良县| 延寿县| 绥德县| 涞水县| 云安县| 水富县| 高雄市|