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
相关产品推荐
相关产品推荐

