激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 解決spring data redis的那些坑

解決spring data redis的那些坑

2022-01-06 01:09一個松 Java教程

這篇文章主要介紹了spring data redis的那些坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

spring data redis的那些坑

spring 的IOC很少有bug,AOPbug開始多起來,到了它的一些“玩具”一樣的組件,bug無處不在。而且跟一般的開源框架不同,在github上你報告issue,會被“這不是一個bug”強行關(guān)閉。開一博文記錄,給遇到同樣問題而苦惱的人歇歇腳。

1. 使用lua腳本,返回類型解析錯誤

背景:一般來講,就算腳本里沒有return語句,redis也是會返回執(zhí)行結(jié)果,看起來就像:{“Ok” = “ok”},或者{“ok”:”ok”}。然而對于一些操作redis沒有返回,或者return語句后面返回一個值,spring包了的那一層殼就會出問題。影響的包:spring封裝了jedis的所有版本,包括:spring-data-redis 2.0以下的所有版本,以及使用了jedis的2.0以上版本:

?
1
2
3
4
5
6
7
8
9
10
11
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.0.0.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

這種情況下就會遇到

XXX cannot be cast to XXX

原因:DefaultScriptExecutor.java類中:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public <T> T execute(final RedisScript<T> script, final RedisSerializer<?> argsSerializer,
        final RedisSerializer<T> resultSerializer, final List<K> keys, final Object... args) {
    return template.execute((RedisCallback<T>) connection -> {
        final ReturnType returnType = ReturnType.fromJavaType(script.getResultType()); // return type is wrong.
        final byte[][] keysAndArgs = keysAndArgs(argsSerializer, keys, args);
        final int keySize = keys != null ? keys.size() : 0;
        if (connection.isPipelined() || connection.isQueueing()) {
            // We could script load first and then do evalsha to ensure sha is present,
            // but this adds a sha1 to exec/closePipeline results. Instead, just eval
            connection.eval(scriptBytes(script), returnType, keySize, keysAndArgs);
            return null;
        }
        return eval(connection, script, returnType, keySize, keysAndArgs, resultSerializer);
    });
}

而作為消費者,一般會將返回值設(shè)置為Object,因為同一個腳本里有若干的邏輯,不同情況下返回值可能是布爾型,字符串型,Number型等。

?
1
2
3
4
ScriptSource scriptSource = new ResourceScriptSource(new ClassPathResource("META-INF/scripts/redis.lua"));
DefaultRedisScript<Object> redisScript = new DefaultRedisScript<Object>();
redisScript.setScriptSource(scriptSource);
redisScript.setResultType(Object.class);

而DefaultScriptExecutor的execute方法,會把Object類型解析為List類型,進而設(shè)置returnType為Multi。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public Object convert(Object result) {
        if (result instanceof String) {
            // evalsha converts byte[] to String. Convert back for consistency
            return SafeEncoder.encode((String) result);
        }
        if (returnType == ReturnType.STATUS) {
            return JedisConverters.toString((byte[]) result);
        }
        if (returnType == ReturnType.BOOLEAN) {
            // Lua false comes back as a null bulk reply
            if (result == null) {
                return Boolean.FALSE;
            }
            return ((Long) result == 1);
        }
        if (returnType == ReturnType.MULTI) {
            List<Object> resultList = (List<Object>) result;
            List<Object> convertedResults = new ArrayList<>();
            for (Object res : resultList) {
                if (res instanceof String) {
                    // evalsha converts byte[] to String. Convert back for
                    // consistency
                    convertedResults.add(SafeEncoder.encode((String) res));
                } else {
                    convertedResults.add(res);
                }
            }
            return convertedResults;
        }
        return result;
    }

會因為result(原本只是一個Object),被解析為List,轉(zhuǎn)換出了問題。此外,這里居然沒有設(shè)置null的轉(zhuǎn)換,難道null就不是List了。。。好在spring redis基于lettuce的實現(xiàn)不存在這個問題。

2. spring redis基于lettuce配置Client必須顯示調(diào)用

從官方的reference看,spring的lettuce的配置只需要簡單使用一個包含host、port、database、password等鏈接必須信息構(gòu)造的RedisStandaloneConfiguration對象作為參數(shù)傳遞給LettuceConnectionFactory 的構(gòu)造函數(shù),同理連接池,然而實際使用中發(fā)現(xiàn),ConnectionFactory用于建立連接的是從它的client屬性獲取的服務(wù)器地址等,因此必須調(diào)用afterPropertiesSet方法。

現(xiàn)在client信息有了,可以連接,但是連接池又未開啟,盡管已經(jīng)在構(gòu)造器參數(shù)中指定過。受限于時間,還沒有調(diào)這個點。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
LettucePoolingClientConfiguration poolingClientConfiguration = LettucePoolingClientConfiguration.builder()
    .poolConfig(new GenericObjectPoolConfig())
    .build();
 
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(
    redisProperty.getHost(),redisProperty.getPort()
);
redisStandaloneConfiguration.setDatabase(redisProperty.getDatabase());
 
LettuceConnectionFactory cf = new LettuceConnectionFactory(redisStandaloneConfiguration, poolingClientConfiguration);
cf.afterPropertiesSet(); // must
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(cf);
setSerializer(stringRedisTemplate);

spring data redis 的優(yōu)缺點

spring-data-redis是由spring的 cache api 整合 redis 而來,它的命名規(guī)則由spring cache 的規(guī)則來定義key和對key的管理,進一步弱化redis的API。

事實上redis提供的功能已經(jīng)足夠強大,并且可以直接使用,同時支持靈活的分庫。

spring 的 cache 功能主要由 @Cacheable @CacheEvict @CachePut 實現(xiàn)

  • @Cacheable 主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進行緩存
  • @CachePut 主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進行緩存,和 @Cacheable 不同的是,它每次都會觸發(fā)真實方法的調(diào)用
  • @CachEvict 主要針對方法配置,能夠根據(jù)一定的條件對緩存進行清空

默認情況下Spring使用CacheManagerBean 來實現(xiàn),其實現(xiàn)有3種:EHCache,Redis,ConcurrentHashMap,默認的ConcurrentHashMap 是沒有過期的。

Redis 的使用也是要自己手動調(diào) expire ,所以暫時使用原生的 jedis ,直接調(diào)用 redis 的api

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/kakadiablo/article/details/79638082

延伸 · 閱讀

精彩推薦
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發(fā)項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發(fā)現(xiàn)了對于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7482021-02-04
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經(jīng)有好久沒有升過級了。升級完畢重啟之后,突然發(fā)現(xiàn)好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java實現(xiàn)搶紅包功能

    Java實現(xiàn)搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現(xiàn)搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
  • Java教程xml與Java對象的轉(zhuǎn)換詳解

    xml與Java對象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 在线观看国产免费视频 | 色av成人天堂桃色av | 黄色大片免费看 | 久久色播 | 国产1区在线 | 欧美一级毛片欧美一级成人毛片 | 看片一区二区三区 | 圆产精品久久久久久久久久久 | 末成年女av片一区二区 | sm高h视频| 欧美高清一级片 | 国产午夜精品一区二区三区不卡 | 国产精品久久久久久久久久久久久久久 | 欧美一级电影网站 | 欧美亚州| 成人永久视频 | 国产伦精品一区二区三区 | 性欧美xxxx极品摘花 | 亚洲午夜精品视频 | 91成人一区二区三区 | 欧美人禽 | 一级免费特黄视频 | 日韩视频在线观看免费 | 视频在线中文字幕 | 国产精品久久久久久久久久10秀 | 国产精品高清一区 | 成人勉费视频 | av资源在线 | 久国久产久精永久网页 | 午夜精品区 | hd性videos意大利复古 | 失禁高潮抽搐喷水h | 成人毛片网站 | 久久艹综合 | 国产中文av在线 | 九九热精品在线播放 | 伊人亚洲精品 | 特级毛片a级毛片100免费 | 一级在线视频 | 亚洲精品成人18久久久久 | 亚洲第一精品在线 |