Quarkus集成redis操作Redisson实现数据互通

 更新时间:2022年02月23日 09:40:21   作者:kl  
这篇文章主要为大家介绍了Quarkus集成redis操作Redisson实现数据互通的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步

前言

博主所在公司大量使用了redis缓存,redis客户端用的Redisson。在Quarkus集成redis时,博主尝试使用Redisson客户端直接集成,发现,在jvm模式下运行quarkus没点问题,但是在打native image时,就报错了,尝试了很多方式都是莫名其妙的异常。最后决定采用quarkus官方的redis客户端,但是Redisson客户端数据序列化方式是特有的,不是简单的String,所以quarkus中的redis需要操作Redisson的数据,就要保持序列化方式一致,本文就是为了解决这个问题。

Quarkus版本:1.7.0.CR1

集成redis

首先你的quarkus版本一定要1.7.0.CR1版本及以上才行,因为redis的扩展包是这个版本才发布的,添加依赖:

<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

复制Redisson序列化

Redisson里内置了很多的序列化方式,我们用的JsonJacksonCodec,这里将Redisson中的实现复制后,稍加改动,如下:

/**
 * 和Redisson的序列化数据互相反序列化的编解码器
 * @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数据实现互通的详细内容,更多关于Quarkus集成redis操作Redisson数据的资料请关注脚本之家其它相关文章!

相关文章

  • 如何使用Redis锁处理并发问题详解

    如何使用Redis锁处理并发问题详解

    这篇文章主要给大家介绍了关于如何使用Redis锁处理并发问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • Redis5之后版本的高可用集群搭建的实现

    Redis5之后版本的高可用集群搭建的实现

    这篇文章主要介绍了Redis5之后版本的高可用集群搭建的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Redis Stat的安装指南

    Redis Stat的安装指南

    这篇文章主要介绍了Redis Stat的安装指南的相关资料,需要的朋友可以参考下
    2016-04-04
  • Redis中一些最常见的面试问题总结

    Redis中一些最常见的面试问题总结

    Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行各种刁难。下面这篇文章主要给大家总结介绍了关于Redis中一些最常见的面试问题,需要的朋友可以参考下
    2018-09-09
  • Redis与本地缓存的结合实现

    Redis与本地缓存的结合实现

    我们开发中经常用到Redis作为缓存,本文主要介绍了Redis与本地缓存的结合实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Redis不仅仅是缓存,还是……

    Redis不仅仅是缓存,还是……

    Redis是一个开源的(BSD协议),内存中的数据结构存储,它可以用作数据库,缓存,消息代理。这篇文章主要介绍了Redis不仅仅是缓存,还是……,需要的朋友可以参考下
    2020-12-12
  • Redis安装教程图解

    Redis安装教程图解

    Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。本文就教大家如何安装Redis,需要的朋友可以参考下
    2015-10-10
  • Redis操作相关命令之查看、停止、启动命令

    Redis操作相关命令之查看、停止、启动命令

    这篇文章主要介绍了Redis操作相关命令之查看、停止、启动命令,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • 一文弄懂Redis单线程和多线程

    一文弄懂Redis单线程和多线程

    本文主要介绍了一文弄懂Redis单线程和多线程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Redis类型type与编码encoding原理及使用示例

    Redis类型type与编码encoding原理及使用示例

    这篇文章主要为大家介绍了Redis类型type与编码encoding原理及使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03

最新评论