此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Data MongoDB 4.5.2spring-doc.cadn.net.cn

生命周期事件

MongoDB 映射框架包括几个org.springframework.context.ApplicationEvent您的应用程序可以通过在ApplicationContext. 基于 Spring 的ApplicationContext事件基础设施使其他产品(例如 Spring Integration)能够轻松接收这些事件,因为它们是基于 Spring 的应用程序中众所周知的事件机制。spring-doc.cadn.net.cn

实体生命周期事件的成本可能很高,并且在加载大型结果集时,您可能会注意到性能配置文件发生了变化。 您可以在模板 API 上禁用生命周期事件。spring-doc.cadn.net.cn

在对象通过转换过程之前拦截对象(将您的域对象转换为org.bson.Document),您可以注册一个AbstractMongoEventListener覆盖onBeforeConvert方法。 当事件被分派时,你的侦听器被调用并在进入转换器之前传递域对象。 以下示例显示了如何执行此作:spring-doc.cadn.net.cn

public class BeforeConvertListener extends AbstractMongoEventListener<Person> {
  @Override
  public void onBeforeConvert(BeforeConvertEvent<Person> event) {
    ... does some auditing manipulation, set timestamps, whatever ...
  }
}

要在对象进入数据库之前拦截它,您可以注册一个AbstractMongoEventListener覆盖onBeforeSave方法。当事件被分派时,你的侦听器被调用并传递域对象和转换后的com.mongodb.Document.以下示例显示了如何执行此作:spring-doc.cadn.net.cn

public class BeforeSaveListener extends AbstractMongoEventListener<Person> {
  @Override
  public void onBeforeSave(BeforeSaveEvent<Person> event) {
    … change values, delete them, whatever …
  }
}

在 Spring ApplicationContext 中声明这些 bean 会导致每当分派事件时调用它们。spring-doc.cadn.net.cn

回调AbstractMappingEventListener:
  • onBeforeConvert:被调用MongoTemplate insert,insertListsave在对象转换为Document通过MongoConverter.spring-doc.cadn.net.cn

  • onBeforeSave:被调用MongoTemplate insert,insertListsave插入或保存Document在数据库中。spring-doc.cadn.net.cn

  • onAfterSave:被调用MongoTemplate insert,insertListsave插入或保存Document在数据库中。spring-doc.cadn.net.cn

  • onAfterLoad:被调用MongoTemplate find,findAndRemove,findOnegetCollection方法Document已从数据库中检索。spring-doc.cadn.net.cn

  • onAfterConvert:被调用MongoTemplate find,findAndRemove,findOnegetCollection方法Document已从数据库中检索到,已转换为 POJO。spring-doc.cadn.net.cn

生命周期事件仅针对根级别类型发出。 用作文档根目录中属性的复杂类型不受事件发布的影响,除非它们是用@DBRef.
生命周期事件依赖于ApplicationEventMulticaster,如果SimpleApplicationEventMulticaster可以配置为TaskExecutor,因此不保证何时处理事件。

实体回调

Spring Data 基础设施提供了钩子,用于在调用某些方法之前和之后修改实体。 那些所谓的EntityCallback实例提供了一种方便的方法来检查和可能修改回调风格的实体。
EntityCallback看起来很像一个专门的ApplicationListener. 一些 Spring Data 模块发布特定于 store 的事件(例如BeforeSaveEvent) 允许修改给定实体。在某些情况下,例如在使用不可变类型时,这些事件可能会导致麻烦。 此外,事件发布依赖于ApplicationEventMulticaster.如果使用异步配置TaskExecutor它可能会导致不可预测的结果,因为事件处理可以分叉到线程上。spring-doc.cadn.net.cn

实体回调为集成点提供同步和响应式 API,以保证在处理链中定义明确的检查点按顺序执行,返回可能修改的实体或响应式包装器类型。spring-doc.cadn.net.cn

实体回调通常按 API 类型分隔。这种分离意味着同步 API 仅考虑同步实体回调,而响应式实现仅考虑响应式实体回调。spring-doc.cadn.net.cn

Entity Callback API 已在 Spring Data Commons 2.2 中引入。这是应用实体修改的推荐方法。 特定于现有商店ApplicationEvents在调用可能注册之前仍发布EntityCallback实例。spring-doc.cadn.net.cn

实现实体回调

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

解剖EntityCallback
@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.
	 */
	(1)
	T onBeforeSave(T entity, (2)
		String collection); (3)
}
1 BeforeSaveCallback在保存实体之前调用的特定方法。返回可能修改的实例。
2 持久化之前的实体。
3 许多存储特定参数,例如实体持久化到的集合
反应体的剖析EntityCallback
@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.
	 */
	(1)
	Publisher<T> onBeforeSave(T entity, (2)
		String collection); (3)
}
1 BeforeSaveCallback在保存实体之前在订阅时调用的特定方法。发出可能修改的实例。
2 持久化之前的实体。
3 许多存储特定参数,例如实体持久化到的集合
可选的实体回调参数由实现的 Spring Data 模块定义,并从EntityCallback.callback().

实现适合您的应用程序需求的接口,如以下示例所示:spring-doc.cadn.net.cn

示例BeforeSaveCallback
class DefaultingEntityCallback implements BeforeSaveCallback<Person>, Ordered {      (2)

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

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

		return // ...
	}

	@Override
	public int getOrder() {
		return 100;                                                                  (2)
	}
}
1 根据您的要求实现回调。
2 如果同一域类型存在多个实体回调,则可能会对实体回调进行排序。排序遵循最低优先级。

注册实体回调

EntityCallbackbean 由特定于 store 的实现选取,以防它们在ApplicationContext. 大多数模板 API 已经实现ApplicationContextAware因此可以访问ApplicationContextspring-doc.cadn.net.cn

以下示例说明了有效实体回调注册的集合:spring-doc.cadn.net.cn

示例EntityCallback豆注册
@Order(1)                                                           (1)
@Component
class First implements BeforeSaveCallback<Person> {

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

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

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

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

@Configuration
public class EntityCallbackConfiguration {

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

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

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

	@Override
	public Person onBeforeSave(User user) {
		return // ...
	}
}
1 BeforeSaveCallback@Order注解。
2 BeforeSaveCallback通过Ordered接口实现。
3 BeforeSaveCallback使用 lambda 表达式。默认情况下无序,最后调用。请注意,由 lambda 表达式实现的回调不会公开键入信息,因此使用不可分配的实体调用这些回调会影响回调吞吐量。使用classenum为回调 Bean 启用类型过滤。
4 将多个实体回调接口组合在单个实现类中。

存储特定的实体回调

Spring Data MongoDB 使用EntityCallbackAPI 用于其审计支持,并对以下回调做出反应。spring-doc.cadn.net.cn

表 1.支持的实体回传
回调 方法 描述 次序

ReactiveBeforeConvertCallback BeforeConvertCallbackspring-doc.cadn.net.cn

onBeforeConvert(T entity, String collection)spring-doc.cadn.net.cn

在将域对象转换为org.bson.Document.spring-doc.cadn.net.cn

Ordered.LOWEST_PRECEDENCEspring-doc.cadn.net.cn

ReactiveAfterConvertCallback AfterConvertCallbackspring-doc.cadn.net.cn

onAfterConvert(T entity, org.bson.Document target, String collection)spring-doc.cadn.net.cn

在加载域对象后调用。
可以修改域对象,然后从
org.bson.Document.spring-doc.cadn.net.cn

Ordered.LOWEST_PRECEDENCEspring-doc.cadn.net.cn

ReactiveAuditingEntityCallback AuditingEntityCallbackspring-doc.cadn.net.cn

onBeforeConvert(Object entity, String collection)spring-doc.cadn.net.cn

标记已创建修改的可审计实体spring-doc.cadn.net.cn

100spring-doc.cadn.net.cn

ReactiveBeforeSaveCallback BeforeSaveCallbackspring-doc.cadn.net.cn

onBeforeSave(T entity, org.bson.Document target, String collection)spring-doc.cadn.net.cn

在保存域对象之前调用。
可以修改目标,要持久化,
Document包含所有映射的实体信息。spring-doc.cadn.net.cn

Ordered.LOWEST_PRECEDENCEspring-doc.cadn.net.cn

ReactiveAfterSaveCallback AfterSaveCallbackspring-doc.cadn.net.cn

onAfterSave(T entity, org.bson.Document target, String collection)spring-doc.cadn.net.cn

在保存域对象之前调用。
可以修改域对象,保存后返回,
Document包含所有映射的实体信息。spring-doc.cadn.net.cn

Ordered.LOWEST_PRECEDENCEspring-doc.cadn.net.cn

Bean 验证

Spring Data MongoDB支持对用 https://xxx[Jakarta Validation annotations]注释的MongoDB实体进行Bean Validation。spring-doc.cadn.net.cn

您可以通过注册来启用 Bean 验证ValidatingEntityCallback分别ReactiveValidatingEntityCallback用于 Spring 中的响应式驱动程序使用ApplicationContext如以下示例所示:spring-doc.cadn.net.cn

@Configuration
class Config {

  @Bean
  public ValidatingEntityCallback validatingEntityCallback(Validator validator) {
    return new ValidatingEntityCallback(validator);
  }
}
@Configuration
class Config {

  @Bean
  public ReactiveValidatingEntityCallback validatingEntityCallback(Validator validator) {
    return new ReactiveValidatingEntityCallback(validator);
  }
}

如果您同时使用命令式和响应式,那么您也可以同时启用这两个回调。spring-doc.cadn.net.cn

使用基于 XML 的配置时,从历史上看,ValidatingMongoEventListener在配置时通过我们的命名空间处理程序注册<mongo:mapping-converter>. 如果要使用较新的实体回调变体,请确保不要使用<mongo:mapping-converter>,否则你最终会同时得到两者,ValidatingMongoEventListenerValidatingEntityCallback正在注册。