前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring中国教育管理中心-Apache Cassandra 的 Spring 数据教程十四

Spring中国教育管理中心-Apache Cassandra 的 Spring 数据教程十四

原创
作者头像
IT胶囊
发布2021-12-17 14:37:12
1.6K0
发布2021-12-17 14:37:12
举报
文章被收录于专栏:IT技能应用

14.8.1.实现实体回调

AnEntityCallback通过其泛型类型参数直接与其域类型相关联。每个 Spring Data 模块通常带有一组EntityCallback涵盖实体生命周期的预定义接口。

例 118. 解剖 EntityCallback

代码语言:javascript
复制
@FunctionalInterface
public interface BeforeSaveCallback<T> extends EntityCallback<T> {

  /**
   * Entity callback method invoked before a domain object is saved.
   * Can return either the same or a modified instance.
   *
   * @return the domain object to be persisted.
   */
  T onBeforeSave(T entity <2>, String collection <3>); 
}

BeforeSaveCallback在保存实体之前要调用的特定方法。返回一个可能被修改的实例。

在持久化之前的实体。

许多存储特定参数,例如实体持久化到的集合。

例 119. 反应式的剖析 EntityCallback

代码语言:javascript
复制
@FunctionalInterface
public interface ReactiveBeforeSaveCallback<T> extends EntityCallback<T> {

  /**
   * Entity callback method invoked on subscription, before a domain object is saved.
   * The returned Publisher can emit either the same or a modified instance.
   *
   * @return Publisher emitting the domain object to be persisted.
   */
  Publisher<T> onBeforeSave(T entity <2>, String collection <3>); 
}

BeforeSaveCallback在保存实体之前,在订阅时调用的特定方法。发出一个可能被修改的实例。

在持久化之前的实体。

许多存储特定参数,例如实体持久化到的集合。

可选的实体回调参数由实现 Spring Data 模块定义并从EntityCallback.callback().

实现适合您的应用程序需求的接口,如下例所示:

示例 120. 示例 BeforeSaveCallback

代码语言:javascript
复制
class DefaultingEntityCallback implements BeforeSaveCallback<Person>, Ordered {      

  @Override
  public Object onBeforeSave(Person entity, String collection) {                   

    if(collection == "user") {
        return // ...
    }

    return // ...
  }

  @Override
  public int getOrder() {
    return 100;                                                                  
  }
}

根据您的要求实现回调。

如果存在多个相同域类型的实体回调,则可能对实体回调进行排序。排序遵循最低优先级。

14.8.2.注册实体回调

EntityCallback如果 bean 在ApplicationContext. 大多数模板 API 已经实现ApplicationContextAware,因此可以访问ApplicationContext

以下示例解释了一组有效的实体回调注册:

示例 121. EntityCallbackBean 注册示例

代码语言:javascript
复制
@Order(1)                                                           
@Component
class First implements BeforeSaveCallback<Person> {

  @Override
  public Person onBeforeSave(Person person) {
    return // ...
  }
}

@Component
class DefaultingEntityCallback implements BeforeSaveCallback<Person>,
                                                           Ordered { 

  @Override
  public Object onBeforeSave(Person entity, String collection) {
    // ...
  }

  @Override
  public int getOrder() {
    return 100;                                                  
  }
}

@Configuration
public class EntityCallbackConfiguration {

    @Bean
    BeforeSaveCallback<Person> unorderedLambdaReceiverCallback() {   
        return (BeforeSaveCallback<Person>) it -> // ...
    }
}

@Component
class UserCallbacks implements BeforeConvertCallback<User>,
                                        BeforeSaveCallback<User> {   

  @Override
  public Person onBeforeConvert(User user) {
    return // ...
  }

  @Override
  public Person onBeforeSave(User user) {
    return // ...
  }
}
Spring中国教育管理中心-Apache Cassandra 的 Spring 数据教程十四
Spring中国教育管理中心-Apache Cassandra 的 Spring 数据教程十四

BeforeSaveCallback从@Order注释中接收其命令。

BeforeSaveCallback通过Ordered接口实现接收其订单。

BeforeSaveCallback使用 lambda 表达式。默认情况下无序并最后调用。请注意,由 lambda 表达式实现的回调不会公开类型信息,因此使用不可分配的实体调用这些会影响回调吞吐量。使用classorenum为回调 bean 启用类型过滤。

在单个实现类中组合多个实体回调接口。

14.8.3.存储特定的 EntityCallbacks

Spring Data for Apache Cassandra 使用EntityCallbackAPI 来提供审计支持并对以下回调做出反应。

Spring中国教育管理中心-Apache Cassandra 的 Spring 数据教程十四
Spring中国教育管理中心-Apache Cassandra 的 Spring 数据教程十四

15. Kotlin 支持

Kotlin是一种面向 JVM(和其他平台)的静态类型语言,它允许编写简洁优雅的代码,同时提供与用 Java 编写的现有库的出色互操作性。

Spring Data 为 Kotlin 提供一流的支持,让开发人员几乎可以像编写 Kotlin 原生框架一样编写 Kotlin 应用程序。

使用 Kotlin 构建 Spring 应用程序的最简单方法是利用 Spring Boot 及其专用的 Kotlin 支持。本综合教程将教您如何使用start.spring.io使用 Kotlin 构建 Spring Boot 应用程序。

15.1.要求

Spring Data 支持 Kotlin 1.3 并要求kotlin-stdlib(或其变体之一,例如kotlin-stdlib-jdk8)和kotlin-reflect存在于类路径中。如果您通过start.spring.io引导 Kotlin 项目,则默认提供这些。

15.2.零安全

Kotlin 的关键特性之一是空安全,它null在编译时干净地处理值。这通过可空性声明和“值或无值”语义的表达使应用程序更安全,而无需支付包装器的成本,例如Optional. (Kotlin 允许使用具有可为空值的函数式构造。请参阅Kotlin 空值安全性综合指南。)

尽管 Java 不允许您在其类型系统中表达空安全性,但 Spring Data API 使用包中声明的JSR-305工具友好注释进行了注释org.springframework.lang。默认情况下,来自 Kotlin 中使用的 Java API 的类型被识别为平台类型,对其进行空检查。 Kotlin 对 JSR-305 注释和 Spring 可空性注释的支持为Kotlin 开发人员提供了整个 Spring Data API 的空安全,具有null在编译时处理相关问题的优势。

请参阅存储库方法的空处理如何将空安全应用于 Spring 数据存储库。

您可以通过添加-Xjsr305带有以下选项的编译器标志来配置 JSR-305 检查:-Xjsr305={strict|warn|ignore}.

对于 Kotlin 1.1+ 版本,默认行为与-Xjsr305=warn. strict考虑到 Spring Data API 空安全,该值是必需的。Kotlin 类型是从 Spring API 推断出来的,但在使用时应该知道 Spring API 可空性声明可以演变,即使在次要版本之间也是如此,并且将来可能会添加更多检查。

尚不支持通用类型参数、可变参数和数组元素可空性,但应在即将发布的版本中提供。

15.3.对象映射

有关Kotlin对象如何具体化的详细信息,请参阅Kotlin 支持。

15.4.扩展

Kotlin扩展提供了使用附加功能扩展现有类的能力。Spring Data Kotlin API 使用这些扩展为现有的 Spring API 添加新的 Kotlin 特定的便利。

请记住,需要导入 Kotlin 扩展才能使用。与静态导入类似,IDE 应该在大多数情况下自动建议导入。

例如,Kotlin reified 类型参数为 JVM泛型类型擦除提供了一种解决方法,Spring Data 提供了一些扩展来利用此功能。这允许更好的 Kotlin API。

要SWCharacter在 Java 中检索对象列表,您通常会编写以下内容:

代码语言:javascript
复制
Flux<SWCharacter> characters = template.query(SWCharacter.class).inTable("star-wars").all()

使用 Kotlin 和 Spring Data 扩展,您可以改为编写以下内容:

代码语言:javascript
复制
val characters = template.query<SWCharacter>().inTable("star-wars").all()
// or (both are equivalent)
val characters : Flux<SWCharacter> = template.query().inTable("star-wars").all()

在 Java 中,charactersKotlin 是强类型的,但 Kotlin 巧妙的类型推断允许使用更短的语法。

Spring Data for Apache Cassandra 提供以下扩展:

  • 为具体化泛型的支持CassandraOperations(包括异步和反应性的变体), CqlOperations(包括异步和反应性变体)FluentCassandraOperations,ReactiveFluentCassandraOperations,Criteria,和Query。
  • 的协程扩展ReactiveFluentCassandraOperations。

15.5.协程

Kotlin协程是轻量级线程,允许强制编写非阻塞代码。在语言方面,suspend函数为异步操作提供了抽象,而在库方面kotlinx.coroutines提供了async { }像Flow.

Spring Data 模块在以下范围内提供对协程的支持:

  • Kotlin 扩展中的延迟和流返回值支持

15.5.1.依赖关系

协同程序支持时启用kotlinx-coroutines-core, kotlinx-coroutines-reactive而且kotlinx-coroutines-reactor依赖在类路径中:

示例 122. 在 Maven pom.xml 中添加的依赖项

代码语言:javascript
复制
<dependency>
  <groupId>org.jetbrains.kotlinx</groupId>
  <artifactId>kotlinx-coroutines-core</artifactId>
</dependency>

<dependency>
  <groupId>org.jetbrains.kotlinx</groupId>
  <artifactId>kotlinx-coroutines-reactive</artifactId>
</dependency>

<dependency>
  <groupId>org.jetbrains.kotlinx</groupId>
  <artifactId>kotlinx-coroutines-reactor</artifactId>
</dependency>

支持的版本1.3.0及以上。

15.5.2.反应如何转化为协程?

对于返回值,从 Reactive 到 Coroutines API 的转换如下:

  • fun handler(): Mono<Void> 变成 suspend fun handler()
  • fun handler(): Mono<T>成为suspend fun handler(): T或suspend fun handler(): T?取决于是否Mono可以为空(具有更静态类型的优点)
  • fun handler(): Flux<T> 变成 fun handler(): Flow<T>

FlowFlux在 Coroutines 世界中是等价的,适用于热流或冷流,有限流或无限流,主要区别如下:

  • Flow是基于推的,Flux而是推拉混合的
  • 背压是通过挂起函数实现的
  • Flow只有一个挂起collect方法,操作符作为扩展实现
  • 由于协程,运算符易于实现
  • 扩展允许添加自定义运算符 Flow
  • 收集操作正在暂停功能
  • map运算符支持异步操作(不需要flatMap),因为它需要一个挂起函数参数

阅读这篇关于Going Reactive with Spring、Coroutines 和 Kotlin Flow 的博客文章,了解更多详细信息,包括如何与 Coroutines 并发运行代码。

15.5.3.存储库

这是一个 Coroutines 存储库的示例:

代码语言:javascript
复制
interface CoroutineRepository : CoroutineCrudRepository<User, String> {

    suspend fun findOne(id: String): User

    fun findByFirstname(firstname: String): Flow<User>

    suspend fun findAllByFirstname(id: String): List<User>
}

协程存储库建立在反应式存储库上,以通过 Kotlin 的协程公开数据访问的非阻塞特性。协程存储库上的方法可以由查询方法或自定义实现支持。如果自定义方法是可调用的,则调用自定义实现方法会将 Coroutines 调用传播到实际实现方法,suspend而无需实现方法返回反应类型,例如Mono或Flux。

协程存储库仅在存储库扩展CoroutineCrudRepository接口时才被发现。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 14.8.1.实现实体回调
  • 14.8.2.注册实体回调
  • 14.8.3.存储特定的 EntityCallbacks
  • 15. Kotlin 支持
  • 15.1.要求
  • 15.2.零安全
  • 15.3.对象映射
  • 15.4.扩展
  • 15.5.协程
  • 15.5.1.依赖关系
  • 15.5.2.反应如何转化为协程?
  • 15.5.3.存储库
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档