@Override
    public Mono<Void> doExecute(final ServerWebExchange exchange, final ShenyuPluginChain chain,
                                final SelectorData selector, final RuleData rule) {
        ICache cache = CacheUtils.getCache();
        if (Objects.nonNull(cache)) {
            return cache.getData(CacheUtils.dataKey(exchange))
                    .zipWith(cache.getData(CacheUtils.contentTypeKey(exchange)))
                    .flatMap(data -> Mono.just(Optional.of(data)))
                    .defaultIfEmpty(Optional.empty())
                    .flatMap(dataFlg -> {
                        if (dataFlg.isPresent()) {
                            byte[] bytes = dataFlg.get().getT1();
                            byte[] contentTypeBytes = dataFlg.get().getT2();
                            cache.setContentType(exchange, contentTypeBytes);
                            return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(bytes))
                                    .doOnNext(data -> exchange.getResponse().getHeaders().setContentLength(data.readableByteCount())));
                        }
                        CacheRuleHandle cacheRuleHandle = buildRuleHandle(rule);
                        return chain.execute(exchange.mutate().response(new CacheHttpResponse(exchange, cacheRuleHandle)).build());
                    });
        }
        CacheRuleHandle cacheRuleHandle = buildRuleHandle(rule);
        return chain.execute(exchange.mutate().response(new CacheHttpResponse(exchange, cacheRuleHandle)).build());
    }
@Test
    public void pluginTest() {
        ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("localhost").build());
        final CachePlugin cachePlugin = new CachePlugin();
        final ShenyuPluginChain shenyuPluginChain = mock(ShenyuPluginChain.class);
        final RuleData ruleData = new RuleData();
        CachePluginDataHandler.CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(ruleData), new CacheRuleHandle());
        Mockito.when(shenyuPluginChain.execute(any())).thenReturn(Mono.empty());
        final Mono<Void> result = cachePlugin.doExecute(exchange, shenyuPluginChain, null, ruleData);
        StepVerifier.create(result).expectSubscription().verifyComplete();
        final MemoryCache memoryCache = new MemoryCache();
        Singleton.INST.single(ICache.class, memoryCache);
        final Mono<Void> result2 = cachePlugin.doExecute(exchange, shenyuPluginChain, null, ruleData);
        StepVerifier.create(result2).expectSubscription().verifyComplete();

        memoryCache.cacheData(CacheUtils.dataKey(exchange), MediaType.APPLICATION_JSON_VALUE.getBytes(StandardCharsets.UTF_8),
                60L).subscribeOn(Schedulers.boundedElastic()).subscribe();

        memoryCache.cacheData(CacheUtils.contentTypeKey(exchange), MediaType.APPLICATION_JSON_VALUE.getBytes(StandardCharsets.UTF_8),
                60L).subscribeOn(Schedulers.boundedElastic()).subscribe();
        final Mono<Void> result3 = cachePlugin.doExecute(exchange, shenyuPluginChain, null, ruleData);
        StepVerifier.create(result3).expectSubscription().verifyComplete();
    }