You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:57:01