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

简介: Spring认证中国教育管理中心-Apache Cassandra 的 Spring 数据教程十

13.1.基本
Spring Data 提供了复杂的支持,以透明地跟踪谁创建或更改了实体以及更改发生的时间。要从该功能中受益,您必须为实体类配备审计元数据,这些元数据可以使用注释或通过实现接口来定义。此外,必须通过 Annotation 配置或 XML 配置启用审计以注册所需的基础架构组件。有关配置示例,请参阅特定于商店的部分。

仅跟踪创建和修改日期的应用程序不需要指定AuditorAware.

13.1.1.基于注解的审计元数据
我们提供@CreatedBy并@LastModifiedBy捕获创建或修改实体的用户,@CreatedDate并@LastModifiedDate捕获更改发生的时间。

示例 94. 一个被审计的实体

class Customer {

@CreatedBy
private User user;

@CreatedDate
private Instant createdDate;

// … further properties omitted
}
如您所见,可以有选择地应用注释,具体取决于您要捕获的信息。进行更改时捕获的注释可用于 Joda-Time DateTime、旧版 JavaDate和Calendar、JDK8 日期和时间类型以及long或类型的属性Long。

审计元数据不一定需要存在于根级实体中,但可以添加到嵌入式实体中(取决于实际使用的存储),如下面的截图所示。

示例 95. 审计嵌入实体中的元数据

class Customer {

private AuditMetadata auditingMetadata;

// … further properties omitted
}

class AuditMetadata {

@CreatedBy
private User user;

@CreatedDate
private Instant createdDate;

}
13.1.2.基于接口的审计元数据
如果您不想使用注释来定义审计元数据,您可以让您的域类实现该Auditable接口。它公开了所有审计属性的 setter 方法。

13.1.3.AuditorAware
如果您使用@CreatedBy或@LastModifiedBy,审计基础结构需要以某种方式了解当前主体。为此,我们提供了一个AuditorAwareSPI 接口,您必须实现该接口以告知基础设施当前与应用程序交互的用户或系统是谁。泛型类型T定义了用什么类型注释的属性@CreatedBy或@LastModifiedBy必须是什么类型。

以下示例显示了使用 Spring SecurityAuthentication对象的接口的实现:

Example 96.AuditorAware基于 Spring Security 的实现

class SpringSecurityAuditorAware implements AuditorAware {

@Override
public Optional getCurrentAuditor() {

return Optional.ofNullable(SecurityContextHolder.getContext())
        .map(SecurityContext::getAuthentication)
        .filter(Authentication::isAuthenticated)
        .map(Authentication::getPrincipal)
        .map(User.class::cast);

}
}
该实现访问AuthenticationSpring Security 提供的对象并查找UserDetails您在UserDetailsService实现中创建的自定义实例。我们在这里假设您通过UserDetails实现公开域用户,但根据Authentication发现,您也可以从任何地方查找它。

13.1.4.ReactiveAuditorAware
使用反应式基础架构时,您可能希望使用上下文信息来提供@CreatedBy或提供@LastModifiedBy信息。我们提供了一个ReactiveAuditorAwareSPI 接口,您必须实现该接口才能告诉基础设施当前与应用程序交互的用户或系统是谁。泛型类型T定义了用什么类型注释的属性@CreatedBy或@LastModifiedBy必须是什么类型。

以下示例显示了使用响应式 Spring SecurityAuthentication对象的接口的实现:

例 97.ReactiveAuditorAware基于 Spring Security 的实现

class SpringSecurityAuditorAware implements ReactiveAuditorAware {

@Override
public Mono getCurrentAuditor() {

return ReactiveSecurityContextHolder.getContext()
            .map(SecurityContext::getAuthentication)
            .filter(Authentication::isAuthenticated)
            .map(Authentication::getPrincipal)
            .map(User.class::cast);

}
}
该实现访问AuthenticationSpring Security 提供的对象并查找UserDetails您在UserDetailsService实现中创建的自定义实例。我们在这里假设您通过UserDetails实现公开域用户,但根据Authentication发现,您也可以从任何地方查找它。

13.2.Cassandra 的一般审计配置
要激活审计功能,请将 Spring Data for Apache Cassandraauditing命名空间元素添加到您的配置中,如以下示例所示:

示例 98. 使用 XML 配置激活审计

<cassandra:auditing mapping-context-ref="customMappingContext" auditor-aware-ref="yourAuditorAwareImpl"/>
或者,可以通过使用注释对配置类进行@EnableCassandraAuditing注释来启用审计,如以下示例所示:

示例 99. 使用 JavaConfig 激活审计

@Configuration
@EnableCassandraAuditing
class Config {

@Bean
public AuditorAware myAuditorProvider() {

  return new AuditorAwareImpl();

}
}
如果你暴露类型的豆AuditorAware到ApplicationContext,审计基础设施自动捡起来,并用它来确定当前用户要在域类型设置。如果您在 中注册了多个实现,则ApplicationContext可以通过显式设置 的auditorAwareRef属性来选择要使用的一个@EnableCassandraAuditing。

要启用审计,利用反应式编程模型,请使用@
EnableReactiveCassandraAuditing注释。
如果你暴露类型的豆ReactiveAuditorAware到ApplicationContext,审计基础设施自动捡起来,并用它来确定当前用户要在域类型设置。如果您在 中注册了多个实现,则ApplicationContext可以通过显式设置 的auditorAwareRef属性来选择要使用的一个@
EnableReactiveCassandraAuditing。

示例 100. 使用 JavaConfig 激活反应式审计

@Configuration
@EnableReactiveCassandraAuditing
class Config {

@Bean
public ReactiveAuditorAware myAuditorProvider() {

  return new AuditorAwareImpl();

}
}

  1. 映射

丰富的对象映射支持由
MappingCassandraConverter. MappingCassandraConverter拥有丰富的元数据模型,提供完整的功能特性集以将域对象映射到 CQL 表。

映射元数据模型是通过使用域对象上的注释来填充的。然而,基础设施不限于使用注释作为元数据的唯一来源。该MappingCassandraConverter还允许你映射域对象到表,而不用提供任何额外的元数据,通过以下一组约定。

在本章中,我们描述了 的特性MappingCassandraConverter,如何使用约定将域对象映射到表,以及如何使用基于注释的映射元数据覆盖这些约定。

14.1.对象映射基础
本节涵盖 Spring Data 对象映射、对象创建、字段和属性访问、可变性和不变性的基础知识。请注意,本节仅适用于不使用底层数据存储(如 JPA)的对象映射的 Spring Data 模块。此外,请务必查阅特定于存储的部分以获取特定于存储的对象映射,例如索引、自定义列或字段名称等。

Spring Data 对象映射的核心职责是创建域对象的实例并将存储本机数据结构映射到这些实例上。这意味着我们需要两个基本步骤:

使用公开的构造函数之一创建实例。
实例填充以实现所有公开的属性。
14.1.1.对象创建
Spring Data 会自动尝试检测要用于具体化该类型对象的持久实体的构造函数。解析算法的工作原理如下:

如果只有一个构造函数,则使用它。
如果有多个构造函数并且只有一个用 注释@PersistenceConstructor,则使用它。
如果存在无参数构造函数,则使用它。其他构造函数将被忽略。
值解析假定构造函数参数名称与实体的属性名称匹配,即解析将被执行,就像要填充属性一样,包括映射中的所有自定义(不同的数据存储列或字段名称等)。这还需要类文件中可用的参数名称信息或@ConstructorProperties构造函数中存在的注释。

可以通过使用@Value特定于商店的 SpEL 表达式使用 Spring Framework 的值注释来自定义值解析。有关更多详细信息,请参阅有关商店特定映射的部分。

对象创建内部

为了避免反射的开销,Spring Data 对象创建默认使用运行时生成的工厂类,它会直接调用域类构造函数。即对于此示例类型:

class Person {
Person(String firstname, String lastname) { … }
}
我们将在运行时创建一个语义上等同于这个的工厂类:

class PersonObjectInstantiator implements ObjectInstantiator {

Object newInstance(Object... args) {

return new Person((String) args[0], (String) args[1]);

}
}
这使我们比反射提高了大约 10% 的性能。要使域类有资格进行此类优化,它需要遵守一组约束:

它不能是私人课程
它不能是非静态内部类
它不能是 CGLib 代理类
Spring Data 使用的构造函数不能是私有的
如果这些条件中的任何一个匹配,Spring Data 将通过反射回退到实体实例化。

Spring认证中国教育管理中心-Apache Cassandra 的 Spring 数据教程十
14.1.2.物业人口
一旦创建了实体的实例,Spring Data 就会填充该类的所有剩余持久属性。除非实体的构造函数已经填充(即通过其构造函数参数列表消耗),标识符属性将首先填充以允许循环对象引用的解析。之后,所有尚未由构造函数填充的非瞬态属性都在实体实例上设置。为此,我们使用以下算法:

如果属性是不可变的但公开了一个with…方法(见下文),我们使用该with…方法创建一个具有新属性值的新实体实例。
如果定义了属性访问(即通过 getter 和 setter 访问),我们将调用 setter 方法。
如果属性是可变的,我们直接设置字段。
如果属性是不可变的,我们将使用持久性操作(请参阅对象创建)使用的构造函数来创建实例的副本。
默认情况下,我们直接设置字段值。
财产人口内部结构

与我们在对象构造中的优化类似,我们也使用 Spring Data 运行时生成的访问器类与实体实例进行交互。

class Person {

private final Long id;
private String firstname;
private @AccessType(Type.PROPERTY) String lastname;

Person() {

this.id = null;

}

Person(Long id, String firstname, String lastname) {

// Field assignments

}

Person withId(Long id) {

return new Person(id, this.firstname, this.lastame);

}

void setLastname(String lastname) {

this.lastname = lastname;

}
}
示例 101. 生成的属性访问器

class PersonPropertyAccessor implements PersistentPropertyAccessor {

private static final MethodHandle firstname;

private Person person;

public void setProperty(PersistentProperty property, Object value) {

String name = property.getName();

if ("firstname".equals(name)) {
  firstname.invoke(person, (String) value);             
} else if ("id".equals(name)) {
  this.person = person.withId((Long) value);            
} else if ("lastname".equals(name)) {
  this.person.setLastname((String) value);              
}

}
}
Spring认证中国教育管理中心-Apache Cassandra 的 Spring 数据教程十
PropertyAccessor 持有底层对象的可变实例。这是为了启用其他不可变属性的突变。

默认情况下,Spring Data 使用字段访问来读取和写入属性值。根据private字段的可见性规则,MethodHandles用于与字段进行交互。

该类公开了一个withId(…)用于设置标识符的方法,例如,当一个实例插入到数据存储中并生成一个标识符时。调用withId(…)创建一个新Person对象。所有后续的突变都将在新实例中发生,而前一个则保持不变。

使用属性访问允许直接方法调用而不使用MethodHandles.

这使我们比反射提高了大约 25% 的性能。要使域类有资格进行此类优化,它需要遵守一组约束:

类型不得位于默认值或java包下。

类型及其构造函数必须是 public

属于内部类的类型必须是static.

使用的 Java 运行时必须允许在原始ClassLoader. Java 9 和更新版本施加了某些限制。

默认情况下,Spring Data 尝试使用生成的属性访问器,如果检测到限制,则回退到基于反射的访问器。

让我们看一下以下实体:

示例 102. 示例实体

class Person {

private final @Id Long id;
private final String firstname, lastname;
private final LocalDate birthday;
private final int age;

private String comment;
private @AccessType(Type.PROPERTY) String remarks;

static Person of(String firstname, String lastname, LocalDate birthday) {

return new Person(null, firstname, lastname, birthday,
  Period.between(birthday, LocalDate.now()).getYears());

}

Person(Long id, String firstname, String lastname, LocalDate birthday, int age) {

this.id = id;
this.firstname = firstname;
this.lastname = lastname;
this.birthday = birthday;
this.age = age;

}

Person withId(Long id) {

return new Person(id, this.firstname, this.lastname, this.birthday, this.age);

}

void setRemarks(String remarks) {

this.remarks = remarks;

}
}
Spring认证中国教育管理中心-Apache Cassandra 的 Spring 数据教程十
identifier 属性是最终的,但null在构造函数中设置为。该类公开了一个withId(…)用于设置标识符的方法,例如,当一个实例插入到数据存储中并生成一个标识符时。Person创建新实例时,原始实例保持不变。相同的模式通常应用于由存储管理但可能必须为持久性操作更改的其他属性。wither 方法是可选的,因为持久性构造函数(参见 6)实际上是一个复制构造函数,并且设置该属性将被转换为创建一个应用新标识符值的新实例。

的firstname和lastname特性是通过吸气剂可能暴露普通不可变属性。

该age属性是不可变的,但源自该birthday属性。使用所示设计,数据库值将胜过默认值,因为 Spring Data 使用唯一声明的构造函数。即使意图是计算应该是首选,重要的是此构造函数也将age作为参数(可能会忽略它),否则属性填充步骤将尝试设置年龄字段并由于它不可变且没有with…方法而失败在场。

该comment属性是可变的,通过直接设置其字段来填充。

的remarks特性是可变的,并且通过设置填充comment直接字段或通过调用用于setter方法

该类公开了一个工厂方法和一个用于创建对象的构造函数。这里的核心思想是使用工厂方法而不是额外的构造函数,以避免需要通过@PersistenceConstructor. 相反,属性的默认设置是在工厂方法中处理的。

相关文章
|
6月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1096 3
|
5月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
1015 5
|
7月前
|
Java Linux 网络安全
Linux云端服务器上部署Spring Boot应用的教程。
此流程涉及Linux命令行操作、系统服务管理及网络安全知识,需要管理员权限以进行配置和服务管理。务必在一个测试环境中验证所有步骤,确保一切配置正确无误后,再将应用部署到生产环境中。也可以使用如Ansible、Chef等配置管理工具来自动化部署过程,提升效率和可靠性。
761 13
|
4月前
|
人工智能 数据处理 API
阿里云、Ververica、Confluent 与 LinkedIn 携手推进流式创新,共筑基于 Apache Flink Agents 的智能体 AI 未来
Apache Flink Agents 是由阿里云、Ververica、Confluent 与 LinkedIn 联合推出的开源子项目,旨在基于 Flink 构建可扩展、事件驱动的生产级 AI 智能体框架,实现数据与智能的实时融合。
845 6
阿里云、Ververica、Confluent 与 LinkedIn 携手推进流式创新,共筑基于 Apache Flink Agents 的智能体 AI 未来
|
存储 Cloud Native 数据处理
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
本文整理自阿里云资深技术专家、Apache Flink PMC 成员梅源在 Flink Forward Asia 新加坡 2025上的分享,深入解析 Flink 状态管理系统的发展历程,从核心设计到 Flink 2.0 存算分离架构,并展望未来基于流批一体的通用增量计算方向。
457 0
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
|
6月前
|
SQL 人工智能 数据挖掘
Apache Flink:从实时数据分析到实时AI
Apache Flink 是实时数据处理领域的核心技术,历经十年发展,已从学术项目成长为实时计算的事实标准。它在现代数据架构中发挥着关键作用,支持实时数据分析、湖仓集成及实时 AI 应用。随着 Flink 2.0 的发布,其在流式湖仓、AI 驱动决策等方面展现出强大潜力,正推动企业迈向智能化、实时化的新阶段。
823 9
Apache Flink:从实时数据分析到实时AI
|
6月前
|
SQL 人工智能 API
Apache Flink 2.1.0: 面向实时 Data + AI 全面升级,开启智能流处理新纪元
Apache Flink 2.1.0 正式发布,标志着实时数据处理引擎向统一 Data + AI 平台迈进。新版本强化了实时 AI 能力,支持通过 Flink SQL 和 Table API 创建及调用 AI 模型,新增 Model DDL、ML_PREDICT 表值函数等功能,实现端到端的实时 AI 工作流。同时增强了 Flink SQL 的流处理能力,引入 Process Table Functions(PTFs)、Variant 数据类型,优化流式 Join 及状态管理,显著提升作业稳定性与资源利用率。
735 0
|
5月前
|
人工智能 运维 Java
Flink Agents:基于Apache Flink的事件驱动AI智能体框架
本文基于Apache Flink PMC成员宋辛童在Community Over Code Asia 2025的演讲,深入解析Flink Agents项目的技术背景、架构设计与应用场景。该项目聚焦事件驱动型AI智能体,结合Flink的实时处理能力,推动AI在工业场景中的工程化落地,涵盖智能运维、直播分析等典型应用,展现其在AI发展第四层次——智能体AI中的重要意义。
2004 27
Flink Agents:基于Apache Flink的事件驱动AI智能体框架
|
存储 人工智能 大数据
The Past, Present and Future of Apache Flink
本文整理自阿里云开源大数据负责人王峰(莫问)在 Flink Forward Asia 2024 上海站主论坛开场的分享,今年正值 Flink 开源项目诞生的第 10 周年,借此时机,王峰回顾了 Flink 在过去 10 年的发展历程以及 Flink社区当前最新的技术成果,最后展望下一个十年 Flink 路向何方。
923 33
The Past, Present and Future of Apache Flink

推荐镜像

更多