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

Micronaut中替代PathMatchingResourcePatternResolver加载GraphQL Schema的方案

在Micronaut中批量加载GraphQL Schema文件的实现方案

针对你需要批量加载classpath:graphql/**/*.graphqls格式资源的需求,以下是Micronaut环境下的几种推荐实现方式,均无需依赖Spring组件:

方法一:基于AntPathMatcher精准匹配(通用场景)

利用Micronaut核心的ResourceLoader读取classpath资源,结合AntPathMatcher实现通配符路径匹配,规则与Spring保持一致:

import io.micronaut.core.io.ResourceLoader;
import io.micronaut.core.io.scan.AntPathMatcher;
import jakarta.inject.Singleton;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

@Singleton
public class GraphQLSchemaLoader {

    private final ResourceLoader resourceLoader;
    private final AntPathMatcher pathMatcher;

    // 注入Micronaut原生ResourceLoader
    public GraphQLSchemaLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
        this.pathMatcher = new AntPathMatcher();
    }

    public List<String> loadAllSchemas() throws IOException {
        return resourceLoader.getResources("classpath:")
                .stream()
                // 匹配graphql目录下所有子层级的.graphqls文件
                .filter(resource -> pathMatcher.match("graphql/**/*.graphqls", resource.getPath()))
                .map(resource -> {
                    try {
                        // 读取文件内容
                        return resource.readText();
                    } catch (IOException e) {
                        throw new RuntimeException("读取Schema文件失败: " + resource.getPath(), e);
                    }
                })
                .collect(Collectors.toList());
    }
}

方法二:基于Java NIO Glob匹配(原生Java方式)

借助Java NIO的PathMatcher实现glob模式匹配,适合习惯原生API的场景:

import io.micronaut.core.io.ResourceResolver;
import jakarta.inject.Singleton;
import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.util.List;
import java.util.stream.Collectors;

@Singleton
public class GraphQLSchemaLoader {

    private final ResourceResolver resourceResolver;

    public GraphQLSchemaLoader(ResourceResolver resourceResolver) {
        this.resourceResolver = resourceResolver;
    }

    public List<String> loadAllSchemas() throws IOException {
        // 创建glob匹配器,匹配所有层级下的graphql/**/*.graphqls文件
        PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**/graphql/**/*.graphqls");

        return resourceResolver.getResources("classpath:")
                .stream()
                .map(resource -> URI.create(resource.getURL().toString()))
                .map(Path::of)
                .filter(matcher::matches)
                .map(path -> {
                    try {
                        return Files.readString(path);
                    } catch (IOException e) {
                        throw new RuntimeException("读取Schema文件失败: " + path, e);
                    }
                })
                .collect(Collectors.toList());
    }
}

方法三:直接遍历目标子目录(高效场景,推荐)

由于你的资源仅集中在graphql子目录,直接遍历该目录下的.graphqls文件效率更高,无需遍历整个classpath:

import io.micronaut.core.io.ResourceLoader;
import jakarta.inject.Singleton;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Singleton
public class GraphQLSchemaLoader {

    private final ResourceLoader resourceLoader;

    public GraphQLSchemaLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    public List<String> loadAllSchemas() throws IOException {
        List<String> schemaContents = new ArrayList<>();
        // 遍历classpath下的graphql目录及其子目录
        resourceLoader.forEachResource("classpath:graphql/", resource -> {
            String path = resource.getPath();
            if (path.endsWith(".graphqls")) {
                try {
                    schemaContents.add(resource.readText());
                } catch (IOException e) {
                    throw new RuntimeException("读取Schema文件失败: " + path, e);
                }
            }
        });
        return schemaContents;
    }
}

使用说明

  • 以上类均可通过Micronaut的依赖注入直接使用,比如在GraphQL配置类中注入GraphQLSchemaLoader调用loadAllSchemas()方法。
  • 若资源打包在JAR文件中,ResourceLoader会自动处理JAR内资源的读取,无需额外配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:12:43