private List<Object> getTargetInvokersByRequest(String targetName, List<Object> invokers, Object invocation) {
        Map<String, Object> attachments = parseAttachments(invocation);
        List<String> requestTags = routerConfig.getRequestTags();
        if (CollectionUtils.isEmpty(requestTags)) {
            return invokers;
        }

        // Set of tags used to match instances
        Map<String, String> tags = new HashMap<>();

        // A set of tags used to filter instances, where value is null, indicating that all instances containing the
        // tag are filtered without determining the value value
        Map<String, String> mismatchTags = new HashMap<>();
        for (Map.Entry<String, Object> entry : attachments.entrySet()) {
            String key = entry.getKey();
            if (!requestTags.contains(key)) {
                continue;
            }
            String replaceDashKey = key;
            if (replaceDashKey.contains(RouterConstant.DASH)) {
                // Dubbo will replace the "-" in the key with "."
                replaceDashKey = replaceDashKey.replace(RouterConstant.DASH, RouterConstant.POINT);
            }
            mismatchTags.put(RuleUtils.getMetaKey(replaceDashKey), null);
            String value = Optional.ofNullable(entry.getValue()).map(String::valueOf).orElse(null);
            if (StringUtils.isExist(value)) {
                tags.put(RuleUtils.getMetaKey(replaceDashKey), value);
            }
        }
        if (StringUtils.isExist(tags.get(RouterConstant.META_VERSION_KEY))) {
            mismatchTags.put(RouterConstant.META_VERSION_KEY, tags.get(RouterConstant.META_VERSION_KEY));
        } else {
            // All instances contain version, so null values cannot be stored
            mismatchTags.remove(RouterConstant.META_VERSION_KEY);
        }
        boolean isReturnAllInstancesWhenMismatch = false;
        if (CollectionUtils.isEmpty(mismatchTags)) {
            mismatchTags = allMismatchTags;
            isReturnAllInstancesWhenMismatch = true;
        }
        List<Object> result = RuleStrategyHandler.INSTANCE.getMatchInvokersByRequest(targetName, invokers, tags);
        if (CollectionUtils.isEmpty(result)) {
            result = RuleStrategyHandler.INSTANCE.getMismatchInvokers(targetName, invokers,
                    Collections.singletonList(mismatchTags), isReturnAllInstancesWhenMismatch);
        }
        return result;
    }
@Test
    public void testGetTargetInvokersByRequest() {
        config.setRequestTags(Arrays.asList("foo", "bar", "version"));
        config.setUseRequestRouter(true);
        List<Object> invokers = new ArrayList<>();
        ApacheInvoker<Object> invoker1 = new ApacheInvoker<>("1.0.0",
                Collections.singletonMap(RouterConstant.PARAMETERS_KEY_PREFIX + "bar", "bar1"));
        invokers.add(invoker1);
        ApacheInvoker<Object> invoker2 = new ApacheInvoker<>("1.0.1",
                Collections.singletonMap(RouterConstant.PARAMETERS_KEY_PREFIX + "foo", "bar2"));
        invokers.add(invoker2);
        ApacheInvoker<Object> invoker3 = new ApacheInvoker<>("1.0.1");
        invokers.add(invoker3);
        Invocation invocation = new ApacheInvocation();
        Map<String, String> queryMap = new HashMap<>();
        queryMap.put("side", "consumer");
        queryMap.put("group", "fooGroup");
        queryMap.put("version", "0.0.1");
        queryMap.put("interface", "io.sermant.foo.FooTest");
        DubboCache.INSTANCE.putApplication("io.sermant.foo.FooTest", "foo");

        // Matching instances with foo: bar2
        invocation.setAttachment("foo", "bar2");
        invocation.setAttachment("foo1", "bar2");
        List<Object> targetInvokers = (List<Object>) flowRouteHandler.handle(
                DubboCache.INSTANCE.getApplication("io.sermant.foo.FooTest")
                , invokers, invocation, queryMap, "io.sermant.foo.FooTest");
        Assert.assertEquals(1, targetInvokers.size());
        Assert.assertEquals(invoker2, targetInvokers.get(0));

        // Matching instances with version 1.0.0
        invocation.getObjectAttachments().clear();
        invocation.setAttachment("version", "1.0.0");
        targetInvokers = (List<Object>) flowRouteHandler.handle(DubboCache.INSTANCE.getApplication("io.sermant" +
                        ".foo.FooTest")
                , invokers, invocation, queryMap, "io.sermant.foo.FooTest");
        Assert.assertEquals(1, targetInvokers.size());
        Assert.assertEquals(invoker1, targetInvokers.get(0));
    }