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

Spring Java应用中如何将Network实例传入EventConsumer

实现方案

1. 构造函数注入Network到EventConsumer

直接在创建EventConsumer实例时将Network作为构造参数传入,让消费者初始化时就持有可用的Network引用,适合单次监听场景。

代码示例

EventConsumer 类:

public class EventConsumer {
    private final Network network;

    // 构造函数注入Network
    public EventConsumer(Network network) {
        this.network = network;
    }

    // 事件回调方法,使用network执行后续操作
    public void handleContractEvent(ContractEvent event) {
        // 示例:通过network获取其他合约并执行交易
        Contract processingContract = network.getContract("event-processing-chaincode");
        try {
            processingContract.submitTransaction("handleEvent", new String(event.getPayload()));
        } catch (ContractException | InterruptedException | IOException e) {
            // 处理异常
            e.printStackTrace();
        }
    }
}

EventController 类:

@RestController
public class EventController {
    private final HyperledgerNetworkService networkService;

    public EventController(HyperledgerNetworkService networkService) {
        this.networkService = networkService;
    }

    @PostMapping("/subscribe-contract-events")
    public void subscribeEvents(@RequestParam String channelName, @RequestParam String chaincodeId) {
        // 从服务获取Gateway实例
        Gateway gateway = networkService.getInitializedGateway();
        // 获取目标Network和Contract
        Network network = gateway.getNetwork(channelName);
        Contract contract = network.getContract(chaincodeId);

        // 创建EventConsumer并传入当前Network
        EventConsumer eventConsumer = new EventConsumer(network);
        // 注册事件监听
        contract.addContractListener(eventConsumer::handleContractEvent);
    }
}

2. Lambda捕获传递Network(复用消费者场景)

如果EventConsumer是Spring单例组件,不想每次创建新实例,可以通过Lambda捕获当前Network,在事件触发时传递给消费者的处理方法,适合复用消费者的场景。

代码示例

EventConsumer 类:

@Component
public class EventConsumer {
    // 事件处理方法接收Network参数
    public void handleContractEvent(Network network, ContractEvent event) {
        // 使用network执行操作,比如查询或提交交易
        Contract queryContract = network.getContract("data-query-chaincode");
        try {
            byte[] result = queryContract.evaluateTransaction("getEventRelatedData", new String(event.getPayload()));
            // 处理查询结果
            System.out.println(new String(result));
        } catch (ContractException | InterruptedException | IOException e) {
            e.printStackTrace();
        }
    }
}

EventController 类:

@RestController
public class EventController {
    private final HyperledgerNetworkService networkService;
    private final EventConsumer eventConsumer;

    public EventController(HyperledgerNetworkService networkService, EventConsumer eventConsumer) {
        this.networkService = networkService;
        this.eventConsumer = eventConsumer;
    }

    @PostMapping("/subscribe-contract-events")
    public void subscribeEvents(@RequestParam String channelName, @RequestParam String chaincodeId) {
        Gateway gateway = networkService.getInitializedGateway();
        Network network = gateway.getNetwork(channelName);
        Contract contract = network.getContract(chaincodeId);

        // 通过Lambda捕获当前Network,传递给消费者的处理方法
        contract.addContractListener(event -> eventConsumer.handleContractEvent(network, event));
    }
}

关键注意事项

  • 生命周期匹配:Network实例依赖于Gateway的存活状态,Gateway关闭后Network会失效,需确保在Gateway活跃期间使用Network;如果是长期监听任务,要维护Gateway的存活状态。
  • Spring单例陷阱:如果EventConsumer是Spring单例,不要让它持有Network的长期引用(不同请求可能对应不同Channel的Network),此时优先使用第二种Lambda传递的方式。

内容的提问来源于stack exchange,提问作者gilvictor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:55:21