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

