Quarkus集成redis操作Redisson實(shí)現(xiàn)數(shù)據(jù)互通
前言
博主所在公司大量使用了redis緩存,redis客戶端用的Redisson。在Quarkus集成redis時(shí),博主嘗試使用Redisson客戶端直接集成,發(fā)現(xiàn),在jvm模式下運(yùn)行quarkus沒點(diǎn)問題,但是在打native image時(shí),就報(bào)錯(cuò)了,嘗試了很多方式都是莫名其妙的異常。最后決定采用quarkus官方的redis客戶端,但是Redisson客戶端數(shù)據(jù)序列化方式是特有的,不是簡單的String,所以quarkus中的redis需要操作Redisson的數(shù)據(jù),就要保持序列化方式一致,本文就是為了解決這個(gè)問題。
Quarkus版本:1.7.0.CR1
集成redis
首先你的quarkus版本一定要1.7.0.CR1版本及以上才行,因?yàn)閞edis的擴(kuò)展包是這個(gè)版本才發(fā)布的,添加依賴:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-redis-client</artifactId> </dependency>
新增redis鏈接配置
quarkus.redis.hosts=127.0.0.1:6379 quarkus.redis.database=0 quarkus.redis.timeout=10s quarkus.redis.password=sasa
復(fù)制Redisson序列化
Redisson里內(nèi)置了很多的序列化方式,我們用的JsonJacksonCodec,這里將Redisson中的實(shí)現(xiàn)復(fù)制后,稍加改動(dòng),如下:
/** * 和Redisson的序列化數(shù)據(jù)互相反序列化的編解碼器 * @author keking */ public class JsonJacksonCodec{ public static final JsonJacksonCodec INSTANCE = new JsonJacksonCodec(); @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.PUBLIC_ONLY, setterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE) public static class ThrowableMixIn { } protected final ObjectMapper mapObjectMapper; public JsonJacksonCodec() { this(new ObjectMapper()); } public JsonJacksonCodec(ObjectMapper mapObjectMapper) { this.mapObjectMapper = mapObjectMapper.copy(); init(this.mapObjectMapper); initTypeInclusion(this.mapObjectMapper); } protected void initTypeInclusion(ObjectMapper mapObjectMapper) { TypeResolverBuilder<?> mapTyper = new DefaultTypeResolverBuilder(DefaultTyping.NON_FINAL) { @Override public boolean useForType(JavaType t) { switch (_appliesFor) { case NON_CONCRETE_AND_ARRAYS: while (t.isArrayType()) { t = t.getContentType(); } // fall through case OBJECT_AND_NON_CONCRETE: return (t.getRawClass() == Object.class) || !t.isConcrete(); case NON_FINAL: while (t.isArrayType()) { t = t.getContentType(); } // to fix problem with wrong long to int conversion if (t.getRawClass() == Long.class) { return true; } if (t.getRawClass() == XMLGregorianCalendar.class) { return false; } return !t.isFinal(); // includes Object.class default: // case JAVA_LANG_OBJECT: return t.getRawClass() == Object.class; } } }; mapTyper.init(JsonTypeInfo.Id.CLASS, null); mapTyper.inclusion(JsonTypeInfo.As.PROPERTY); mapObjectMapper.setDefaultTyping(mapTyper); } protected void init(ObjectMapper objectMapper) { objectMapper.setSerializationInclusion(Include.NON_NULL); objectMapper.setVisibility(objectMapper.getSerializationConfig() .getDefaultVisibilityChecker() .withFieldVisibility(JsonAutoDetect.Visibility.ANY) .withGetterVisibility(JsonAutoDetect.Visibility.NONE) .withSetterVisibility(JsonAutoDetect.Visibility.NONE) .withCreatorVisibility(JsonAutoDetect.Visibility.NONE)); objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); objectMapper.enable(Feature.WRITE_BIGDECIMAL_AS_PLAIN); objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); objectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY); objectMapper.addMixIn(Throwable.class, ThrowableMixIn.class); } /** * 解碼器 * @param val * @return */ public Object decoder(String val){ try { ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(); try (ByteBufOutputStream os = new ByteBufOutputStream(buf)) { os.write(val.getBytes()); } return mapObjectMapper.readValue((InputStream) new ByteBufInputStream(buf), Object.class); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 編碼器 * @param obj * @return */ public String encoder(Object obj){ ByteBuf out = ByteBufAllocator.DEFAULT.buffer(); try { ByteBufOutputStream os = new ByteBufOutputStream(out); mapObjectMapper.writeValue((OutputStream) os, obj); return os.buffer().toString(StandardCharsets.UTF_8); } catch (IOException e) { out.release(); } return null; } }
使用
@Dependent @Startup public class Test { @Inject RedisClient redisClient; @Inject Logger logger; void initializeApp(@Observes StartupEvent ev) { //使用JsonJacksonCodec編解碼,保持和redisson互通 JsonJacksonCodec codec = JsonJacksonCodec.INSTANCE; Map<String, String> map = new HashMap<>(); map.put("key","666"); redisClient.set(Arrays.asList("AAAKEY", codec.encoder(map))); String str = redisClient.get("AAAKEY").toString(StandardCharsets.UTF_8); Map<String,String> getVal = (Map<String, String>) codec.decoder(str); logger.info(getVal.get("key")); } }
以上就是Quarkus集成redis操作Redisson數(shù)據(jù)實(shí)現(xiàn)互通的詳細(xì)內(nèi)容,更多關(guān)于Quarkus集成redis操作Redisson數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Redis5之后版本的高可用集群搭建的實(shí)現(xiàn)
這篇文章主要介紹了Redis5之后版本的高可用集群搭建的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Redis與本地緩存的結(jié)合實(shí)現(xiàn)
我們開發(fā)中經(jīng)常用到Redis作為緩存,本文主要介紹了Redis與本地緩存的結(jié)合實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07Redis操作相關(guān)命令之查看、停止、啟動(dòng)命令
這篇文章主要介紹了Redis操作相關(guān)命令之查看、停止、啟動(dòng)命令,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09