使用 KAPT 生成 Kotlin Data Class 转换器

背景 Web 后台开发中,对于一个实体的操作会衍生出多个类似的对象进行操作(避免直接使用实体),由此出现相关名词 持久化对象,即实体 PO(Persistent Object) 传输对象 DTO(Data Transfer Object) 业务对象 BO(Business Object) 展示对象 VO(View Object) 等等…… 这些对象大多数直接从实体里面裁剪几个字段,比如,在一次创建订单请求中以订单实体(OrderEntity)为例,经历如下流程: 1. 接收请求体 CreateOrderRequest 2. 根据 OrderQuery 构造查询对象查询订单 3. 构造 OrderEntity 进行持久化操作 4. 构造 OrderBO 进行下游消费 5. 返回响应体 CreateOrderResponse 可见,从 OrderEntity 衍生出 4 个对象,仅仅是对订单的实体的部分裁剪,但是要编写很多重复的代码(复制也行)。当然,如果是新增字段的话可以使用继承解决。 在 Kotlin Web 后台开发中,data class 的语法特性带来很多优势,但还是避免不了创建类似的重复对象。 所以 Konverter 诞生于此,解决实体对象裁剪问题。还有另一个功能那就是自动生成两个实体间的转换方法。 注意:目前只支持 Kotlin,并且生成的转换方法是通过扩展函数实现 是什么 通过 KAPT(Kotlin Annotation Processing Tool 注解处理以及 Kotlin Poet 代码生成,实现自动生成对实体的相关裁剪的对象。 主要有两个注解: @Konvertable 生成裁剪的实体以及对应的转换方法 @Konvert 单独针对某个类生成转换方法 废话不多说来看怎么使用。 怎么用 1. 引入依赖 // for build....

2020 April 13 · 3 分钟 · Lex Cao

一次线程死锁排查记录

背景 某次发版之后,线上服务低概率出现某台实例接口响应超时,具体表现为: /health 接口超时报警; 线程死锁,Tomcat 线程池吃满; 服务完全无响应。 保留下当前 heap dump 和 thread stack 后,临时重启服务器恢复正常。 # heap dump $ jmap -dump:format=b,file=dump.hprof [pid] # thread stack jstack [pid] > stack.txt 接下来简单记录一下排查结果。 (此文为回忆所写,当时排查的思考细节和过程已省略) 排查 heap dump 使用工具 Eclipse + MAT 安装 # 安装 eclipse $ brew cask install eclipse-java # 安装 eclipse MAT $ brew cask install mat # 是的,这个就是 eclipse-mat 相关连接 Eclipse Eclipse MAT 使用 把 heap dump 文件 dump.hprof 导入到 MAT。...

2020 March 21 · 2 分钟 · Lex Cao

Reactive 概览

Reactive Streams Reactive Streams 在 Netflix 、Pivotal 和 Lightbend 工程师于 2013 年底发起这项计划。 Reactive Streams 是一项提议,为无阻塞背压的异步流提供一个标准。这包括针对运行时环境(JVM 和 JavaScript)以及网络协议上的工作。 你可以在 Reactive Streams 官网网站阅读这个原始规范。 你也可以在 这里 阅读它的中文翻译。 无阻塞背压的异步流处理 Reactive Streams 由以下组成: 异步; 流式; 无阻塞; 背压(回压)。 以下是 Java 接口,你可以在 GitHub 阅读更详细内容。 public interface Publisher<T> { public void subscribe(Subscriber<? super T> s); } public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); } public interface Subscription { public void request(long n); public void cancel(); } public interface Processor<T, R> extends Subscriber<T>, Publisher<R> { } Reactive Extensions 用于可观察流的异步编程 API。...

2019 November 29 · 2 分钟 · Lex Cao

Reactive Streams 规范翻译

翻译自 Reactive Streams Reactive Streams 注:Reactive Streams 直译为响应式流,这里保留英文原词。 Reactive Streams 是一项提议,旨在为具有无阻塞背压的异步处理流提供标准。这包括针对运行环境(JVM 和 JavaScript)以及网络协议的努力。 Reactive Streams 是为了提供一个无阻塞背压异步流式处理的标准的一个提议。 JDK9 java.util.concurrent.Flow 在 JDK 9 的 java.util.concurrent.Flow 中可用的接口,分别为 1 :1 语义上各自对应于 Reactive Streams。这意味着将会有一个迁移期,库(Libraries)将采用 JDK 中的新类型,但是由于库的完全语义等效以及 Reactive Streams <-> Flow 适配器库和直接与 JDK Flow 类型兼容的 TCK,因此这个迁移期预计会很短。 如果你有兴趣了解有关 JVM Reactive Streams,请阅读此 文章 问题 在异步系统中,处理流数据(尤其是数量未先确定的的“实时”数据)需要特别注意。最突出的问题是,需要控制资源消耗,这样快速数据源不会压垮流目的地。为了在并行网络主机或一台多核机器上并行地使用计算资源,需要异步。 Reactive Streams 的主要目标是管理跨异步边界的流数据交换(考虑将元素传递到另一个线程或线程池),同时确保接收方不强制缓存任意数量的数据。换句话说,背压是此模型中不可或缺的一部分,以使在线程之间进行调节的队列收到限制。如果背压的通信是同步的,则异步处理的好处将被抵消(另请看 Reactive Manifesto),因此必须注意对 Reactive Streams 实现的所有方面进行完全无阻塞和异步行为授权。 本说明书旨在允许创建许多符合要求的实现,这些实现通过遵守规则将能够平滑地互相操作,并在流应用程序的整个处理图中保留上述好处和特性。 范围 Reactive Streams 的范围是找接口、方法和协议的最小集,这些接口、方法和协议将描述实现目标——无阻塞背压的异步处理流,所需要的操作和实体。 端用户 DSLs(领域特定语言)或者协议绑定 API(应用编程接口)有目的地被排除在范围之外,以鼓励和支持可能使用不同编程语言的不同实现,以尽可能地遵循其平台的习惯用法。 我们预计,接受这个 Reactive Streams 规范以及它的实现经验将共同导向广泛的集成,例如,包括将来 JDK 版本中的 Java 平台支持或者在将来的网页浏览器中网络协议的支持。...

2019 November 17 · 1 分钟 · Lex Cao

选择一个英文名字

简介 最近我在寻找一个方法给自己取一个英文名字,然后我发现这篇文章,如何选择一个英文名字。该文章在选择一个英文名字提出了一个行之有效的方法,我用该方法制作了一个应用来帮助选择一个英文名字。 你可以在 这里 尝试一下。 我会在下面展开讲一下那篇文章和这个应用。 文章所说 以下是文章原文。 Do not try to be creative in picking an English name. Avoid: Do not try to pick a fun or cute-sounding name from a movie, television, or video game character Do not pick a name that you think sounds cool or trendy, because Americans will think it sounds stupid Do not pick a name because your friends think it sounds cute, because your friends are not the Americans you have to interact with in the future Do not translate some positive-sounding word in your language into English and make that into your name Do:...

2019 November 10 · 2 分钟 · Lex Cao