### CommandLineRunner 多线成异步执行
>1、run方法添加注解@order(1)
2、通过异步线程new Thread(()->{}).start;【线程池不行,会被中断】
```
package com.yl.runner;
import com.yl.service.FabricAssetCommonService;
import lombok.extern.slf4j.Slf4j;
import org.hyperledger.fabric.client.Network;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
/**
* EventListerRunner
*
* @author 王小虎
* @date 2022-02-24 10:13
*/
@Slf4j
@Component
public class EventListerRunner implements CommandLineRunner {
final ChaincodeEventListen chaincodeEventListen;
final FabricAssetCommonService fabricAssetCommonService;
public static final List<String> CHANNEL_LIST = Arrays.asList("yl-channel");
public static final List<String> CHAINCODE_LIST = Arrays.asList("yl_code1","yl_code2");
public EventListerRunner(ChaincodeEventListen chaincodeEventListen, FabricAssetCommonService fabricAssetCommonService) {
this.chaincodeEventListen = chaincodeEventListen;
this.fabricAssetCommonService = fabricAssetCommonService;
}
@Order(1) //第一步
@Override
public void run(String... args) {
Network network = fabricAssetCommonService.getDefault().getNetwork();
CHANNEL_LIST.forEach(c -> {
for (String cc : CHAINCODE_LIST) {
new Thread(() -> {
chaincodeEventListen.exampleChaincodeEvents(network, fabricAssetCommonService.getInstance(c, cc).getContract());
}).start(); //第二步
}
});
}
}
```
```
package com.yl.runner;
import lombok.extern.slf4j.Slf4j;
import org.hyperledger.fabric.client.ChaincodeEvent;
import org.hyperledger.fabric.client.CloseableIterator;
import org.hyperledger.fabric.client.Contract;
import org.hyperledger.fabric.client.Network;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
/**
* ChaincodeEventListen
*
* @author 王小虎
* @date 2022-09-01 11:39
*/
@Slf4j
@Service
public class ChaincodeEventListen {
public void exampleChaincodeEvents(Network network, Contract contractAsset) {
log.info("Read chaincode events: " + contractAsset.getChaincodeName());
try (CloseableIterator<ChaincodeEvent> events = network.getChaincodeEvents(contractAsset.getChaincodeName())) {
while (true) {
CompletableFuture<ChaincodeEvent> readEvent = CompletableFuture.supplyAsync(events::next);
if (!ObjectUtils.isEmpty(readEvent)) {
ChaincodeEvent event = readEvent.get();
log.info("Received event name: " + event.getEventName() +
", payload: " + new String(event.getPayload(), StandardCharsets.UTF_8) +
", txId: " + event.getTransactionId() +
", blockNumber: " + event.getBlockNumber() +
", ccName: " + contractAsset.getChaincodeName());
}
Thread.sleep(50);
}
} catch (Exception e) {
log.error("", e);
}
}
}
```