如何在Micronaut 3中为MongoDB Java Reactive Streams驱动实现生命周期事件
基于MongoDB Reactive Streams驱动实现生命周期事件的方案
MongoDB Reactive Streams驱动和同步驱动共用同一套事件监听体系,你可以通过自定义命令监听器拦截对应的操作命令,即可实现所需的6种生命周期钩子,具体实现步骤如下:
第一步:实现自定义命令监听器
继承CommandListener接口,分别拦截insert、update、delete三类命令的开始和完成事件,对应你需要的Before/After类钩子:
import com.mongodb.event.CommandFailedEvent; import com.mongodb.event.CommandListener; import com.mongodb.event.CommandStartedEvent; import com.mongodb.event.CommandSucceededEvent; import org.bson.BsonDocument; import jakarta.inject.Singleton; @Singleton public class MongoLifecycleListener implements CommandListener { @Override public void commandStarted(CommandStartedEvent event) { String commandName = event.getCommandName(); BsonDocument command = event.getCommand(); // 匹配Before类钩子 switch (commandName) { case "insert" -> beforeInsert(command); case "update" -> beforeUpdate(command); case "delete" -> beforeDelete(command); } } @Override public void commandSucceeded(CommandSucceededEvent event) { String commandName = event.getCommandName(); // 匹配After类钩子(操作成功场景) switch (commandName) { case "insert" -> afterInsert(event.getResponse()); case "update" -> afterUpdate(event.getResponse()); case "delete" -> afterDelete(event.getResponse()); } } @Override public void commandFailed(CommandFailedEvent event) { // 若需要操作失败后的回调逻辑可在此扩展 } // 以下为自定义生命周期方法实现 private void beforeInsert(BsonDocument insertCommand) { // 可从command中解析集合名、待插入文档等信息 String collectionName = insertCommand.getString("insert").getValue(); // 你的业务逻辑 } private void afterInsert(BsonDocument response) { // 可解析插入条数、成功生成的ID等返回信息 long insertedCount = response.getNumber("n").longValue(); // 你的业务逻辑 } private void beforeUpdate(BsonDocument updateCommand) { String collectionName = updateCommand.getString("update").getValue(); // 你的业务逻辑 } private void afterUpdate(BsonDocument response) { long modifiedCount = response.getNumber("nModified").longValue(); // 你的业务逻辑 } private void beforeDelete(BsonDocument deleteCommand) { String collectionName = deleteCommand.getString("delete").getValue(); // 你的业务逻辑 } private void afterDelete(BsonDocument response) { long deletedCount = response.getNumber("n").longValue(); // 你的业务逻辑 } }
第二步:在Micronaut中注册监听器到MongoClient
通过Micronaut提供的MongoClientSettingsBuilderCustomizer配置入口,将上面的监听器注册到MongoClient全局配置中:
import com.mongodb.MongoClientSettings; import io.micronaut.configuration.mongo.reactive.MongoClientSettingsBuilderCustomizer; import jakarta.inject.Singleton; @Singleton public class MongoCustomizer implements MongoClientSettingsBuilderCustomizer { private final MongoLifecycleListener lifecycleListener; public MongoCustomizer(MongoLifecycleListener lifecycleListener) { this.lifecycleListener = lifecycleListener; } @Override public void customize(MongoClientSettings.Builder builder) { // 注册自定义生命周期监听器 builder.addCommandListener(lifecycleListener); } }
第三步:原有代码无需调整
你现有写的Repository代码不需要做任何修改,所有通过注入的MongoClient发起的增删改操作都会自动触发监听器中对应的生命周期方法。
提示:如果需要区分操作所属的数据库,可以在监听器的事件参数中调用
getDatabaseName()方法获取对应库名,避免跨库操作触发不必要的逻辑。
内容的提问来源于stack exchange,提问作者San Jaisy
相关产品推荐
相关产品推荐

