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

使用Java 9模块时,SpringBoot @Value+JavaFX为何需将文件放resources/static?

为什么带module-info.java时Spring Boot的@Value加载资源必须放在resources/static下?

在使用module-info.java的情况下,通过Spring Boot的@Value注解加载XML等文件时,文件必须放置在resources/static/目标路径下,否则会抛出FileNotFoundException异常。目前找到的解决方案包括:删除module-info.java文件、移除org.openjfx.javafxplugin依赖、将XML文件移至resources/static/test/目录下,或是不使用@Value注解。但由于对Java模块机制理解有限,想知道这个问题产生的根源。


最小复现示例

项目结构

build.gradle
src
├───main
│   ├───java
│   │   │   module-info.java
│   │   │
│   │   └───com
│   │       └───example
│   │               App.java
│   │               TestLoader.java
│   │
│   └───resources
│       │   application.properties
│       │
│       ├───static
│       │   └───test
│       │           test.xml
│       │
│       └───test
│               test.xml
│
└───test
    ├───java
│   │   └───com
│   │       └───example
│   │               TestTest.java
│   │
│   └───resources
│           unused

注:unused是一个空文件,用于生成测试资源文件夹以避免报错。

Spring Boot应用类(App.java)

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App
{
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

资源加载类(TestLoader.java)

package com.example;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class TestLoader
{
    private TestLoader(@Value("classpath:test/test.xml") Resource fxml) throws IOException
    {
        fxml.getInputStream();
    }
}

模块信息文件(module-info.java)

module com.example {
    requires spring.boot;
    requires spring.boot.autoconfigure;
    requires spring.context;
    requires spring.core;
    requires spring.beans;

    opens com.example to spring.beans, spring.context, spring.core;
}

Gradle构建文件(build.gradle)

plugins {
  id 'java'
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.13'
  id 'org.springframework.boot' version '3.4.2'
  id 'io.spring.dependency-management' version '1.1.7'
}

group 'com.example'
version '0.0.1-SNAPSHOT'

repositories {
  mavenCentral()
}

java {
  modularity.inferModulePath = true
}

application {
  mainModule = 'com.example'
  mainClass = 'com.example.App'
}

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter'

  testImplementation('org.springframework.boot:spring-boot-starter-test'){
    // https://github.com/spring-cloud/spring-cloud-deployer-kubernetes/issues/142
    exclude group: "com.vaadin.external.google", module:"android-json"
  }
  testImplementation("org.junit.jupiter:junit-jupiter-api")

  testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
  testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
  useJUnitPlatform()
}

测试类(TestTest.java)

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class TestTest {
    @Autowired
    TestLoader loader;

    @Test
    public void test() {
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:47:17