体验的话请使用 3.1.0.0-SNAPSHOT 版本。使用 maven 的 snapshot 版本是需要额外引用 maven snapshot 仓库的。

依赖升级

  • Kotlin 升级至 1.6.0
  • Vert.x 升级至 4.2.1
  • Jackson 升级至 2.12.5

Vert.x 升级至 4.2.1 后已经增加了对 Java 17 的支持。

问题修复

  • 修复 JooqPlugin 在指定连接池类后会导致初始化两遍的问题 #56
  • 删除掉 cloudopt-next-client 中 addHeader 和 addQueryParam,理论上在设置具体路径前是无法设置 head 和 param 的。
  • 兼容 Vert.x 4 设置和删除 cookie 的语法。
  • 修复 cloudopt-next-cache 的健康检查没有统计的问题。

新特性

异步相关

  • 在 3.1.0.0 版本中,已经全面支持了 suspend 关键字声明,包括之前不支持的 Handler、Render 层。但因为从下至上都支持了,所以路由方法必须声明 suspend 关键字才能正常使用。

    1. @GET("/json")
    2. suspend fun jsonRender() {
    3. renderJson(json("result" to "json"))
    4. }

    在之前版本中 render 层为了兼容同步的写法,是独立会开个协程的,那么像是 Handler 之类的地方就不能直接写 render() 方法,必须自己操作 response。现在从下至上的支持了 suspend 后,全面支持了在任意一层使用 render 以及任意的带有 suspend 关键字的方法。#55

  • 移除 Worker.async 关键字,与 Kotlin 后面增加的 async 冲突,而且 runBlocking 目前看起来已经很完善了。

  • 新增 gather 关键字,通过 gather 关键字可以使多个 suspend function 同时执行或者使多个阻塞的代码块同时执行。假如 A 和 B 两个方法分别需要一秒钟,那么传统的编程方法在执行完 A 后执行 B,那么加起来就是两秒,但是 gather 语法可以使两个同时运行,这样只需要一秒。执行多个阻塞代码块实例如下: ```kotlin gather( {
    1. await {
    2. return@await 1
    3. }
    }, {
    1. await {
    2. return@await 2
    3. }
    } )

gather( { suspendFunctionA() }, { suspendFunctionB() } )

  1. <a name="vBwbZ"></a>
  2. ### 数据库相关
  3. - 新增了 cloudopt-next-jdbc 插件,将 jdbc 连接池相关逻辑都抽象到了这个插件,方便以后增加更多的 orm。
  4. - cloudopt-next-jooq 支持多数据源,配置文件改动较大,请升级前阅读相关文档。
  5. - cloudopt-next-jooq 的分页器中 count 字段从最大行数变为实际查询到的结果行数。
  6. - 新增 cloudopt-next-exposed 插件,用于支持 JetBrains 出的 exposed orm。
  7. - cloudopt-next-redis 支持 多数据源,配置文件改动较大,请升级前阅读相关文档。
  8. - cloudopt-next-cache 支持多数据源。
  9. - cloudopt-next-cache 自动设置到 redis 中的 key 增加前缀。
  10. <a name="G2Mja"></a>
  11. ### EventBus 相关
  12. - cloudopt-next-eventbus 的 redis 实现类支持多数据源。
  13. <a name="EoHWq"></a>
  14. ### 加密相关
  15. - 优化了整体的代码逻辑,同时更改了具体的加密实现,大幅度提升了性能。并且现在所有的加密算法都支持加密解密 byte 数组,更有利于文件加密等情况。
  16. 之前的写法,不适合接口直接实现:
  17. ```kotlin
  18. var publicK =
  19. "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCFmf/HWpTZ9smPjyM6SUa0UvUQGfIY+OMV5S8zNqmwz11pYovtz57okRZreK8RtBkBOcOKyk7KRMm0agMm0qBaz0ESuFJmIbl3pEn3l/m0aCNnFv2ehijXl6AoW3bB/fKFoKUcRGXet4R/ka1qcxUJaH3uZtmiyPn8G66BhZXBbQIDAQAB"
  20. var privateK =
  21. "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIWZ/8dalNn2yY+PIzpJRrRS9RAZ8hj44xXlLzM2qbDPXWlii+3PnuiRFmt4rxG0GQE5w4rKTspEybRqAybSoFrPQRK4UmYhuXekSfeX+bRoI2cW/Z6GKNeXoChbdsH98oWgpRxEZd63hH+RrWpzFQlofe5m2aLI+fwbroGFlcFtAgMBAAECgYAZMloS9vprwSdyc8RpEbjL+XlOeBY4r3fkgTzNo9mNBw7O+U76otWNdw+LZU9fP2AX4xUF7/G8JA0GgZfmkoK7VTbpBpX7BeW664GzVa9sDFsf2WMD01J9mndcHjcyyeuwBSXliJupjDAxpDTWcd6U2gMgv0SsTxCZQo2Wdr0y4QJBAPP/OY4Mc68P2bwBXyJcnKZYC0sSgeudZ8URXNbNtEgiklO5SV5hteEBfHYjCzbLf7zE38pMNVtuNua2paNM1kcCQQCMLIKO3wRDQgo/LZxy58kjknAVbZJypZj6Yz8O8poIB2sUyyBPNVOXLg4eOSBMQXH2yJNIw4kv+KAxA+8D2GCrAkEAwHV7Ao7T2SxZhLBYSBRhA9zC2653iFAagBlX759GKvgKD7xBIQ9VlWvErrKpr8kIsu9fzoQaOkpPR+Cd+pcrFQJAfrfmNx5pjhvvg3nKSx46+UtyxAxQLhCCISkDYpHyqXt7VErlJHYC4VKjNLNT/VvUmNJuQ4NxS8qplmYF9yXvDQJAO/GlhZ+qmCOpfKb/pOHRUYSZsPZ0/85sQDQ2u/GYp4jtDqeYNoqZt0Oqr9bEJkJ2sRZnoRGXUePuR7kMoejy9w=="
  22. var e = RsaEncrypt()
  23. e.setPublicKey(publicK).setPrivateKey(privateK)
  24. var s = e.encrypt("hello")
  25. println(s)
  26. println(e.decrypt(s))

现在的写法:

  1. var publicK =
  2. "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCFmf/HWpTZ9smPjyM6SUa0UvUQGfIY+OMV5S8zNqmwz11pYovtz57okRZreK8RtBkBOcOKyk7KRMm0agMm0qBaz0ESuFJmIbl3pEn3l/m0aCNnFv2ehijXl6AoW3bB/fKFoKUcRGXet4R/ka1qcxUJaH3uZtmiyPn8G66BhZXBbQIDAQAB"
  3. var privateK =
  4. "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIWZ/8dalNn2yY+PIzpJRrRS9RAZ8hj44xXlLzM2qbDPXWlii+3PnuiRFmt4rxG0GQE5w4rKTspEybRqAybSoFrPQRK4UmYhuXekSfeX+bRoI2cW/Z6GKNeXoChbdsH98oWgpRxEZd63hH+RrWpzFQlofe5m2aLI+fwbroGFlcFtAgMBAAECgYAZMloS9vprwSdyc8RpEbjL+XlOeBY4r3fkgTzNo9mNBw7O+U76otWNdw+LZU9fP2AX4xUF7/G8JA0GgZfmkoK7VTbpBpX7BeW664GzVa9sDFsf2WMD01J9mndcHjcyyeuwBSXliJupjDAxpDTWcd6U2gMgv0SsTxCZQo2Wdr0y4QJBAPP/OY4Mc68P2bwBXyJcnKZYC0sSgeudZ8URXNbNtEgiklO5SV5hteEBfHYjCzbLf7zE38pMNVtuNua2paNM1kcCQQCMLIKO3wRDQgo/LZxy58kjknAVbZJypZj6Yz8O8poIB2sUyyBPNVOXLg4eOSBMQXH2yJNIw4kv+KAxA+8D2GCrAkEAwHV7Ao7T2SxZhLBYSBRhA9zC2653iFAagBlX759GKvgKD7xBIQ9VlWvErrKpr8kIsu9fzoQaOkpPR+Cd+pcrFQJAfrfmNx5pjhvvg3nKSx46+UtyxAxQLhCCISkDYpHyqXt7VErlJHYC4VKjNLNT/VvUmNJuQ4NxS8qplmYF9yXvDQJAO/GlhZ+qmCOpfKb/pOHRUYSZsPZ0/85sQDQ2u/GYp4jtDqeYNoqZt0Oqr9bEJkJ2sRZnoRGXUePuR7kMoejy9w=="
  5. var e:Encrypt = RsaEncrypt(publicK, privateK)
  6. var s = e.encrypt("hello")
  7. println(s)
  • RSA 算法单次加密从 28ms -> 10ms,提升 180%。
  • AES 算法加密在支持 AES/ECB/PKCS7Padding 的基础上增加了 AES/CBC/PKCS7Padding 的支持。
  • 新增 SM4 算法加密解密支持,目前支持 SM4/ECB/PKCS7Padding 和 SM4/CBC/PKCS7Padding。
  • 新增 SM3 算法加密的支持。
  • 新增 SM2 算法加密解密支持,默认支持的是 C1+C2+C3。