在Spring中的application.properties中指定相对路径

在Spring中的application.properties中指定相对路径,spring,spring-boot,spring-properties,Spring,Spring Boot,Spring Properties,是否有一种方法可以使用Spring boot应用程序中application.properties文件中的相对路径查找文件资源,如下所述 spring.datasource.url=jdbc:hsqldb:file:${project.basedir}/db/init @membersound answer只是将硬编码路径分成两部分,而不是动态解析属性。我可以告诉您如何实现您想要的目标,但您需要了解的是,当您将应用程序作为jar或war运行时,没有project.basedir。在本地工作区之

是否有一种方法可以使用Spring boot应用程序中application.properties文件中的相对路径查找文件资源,如下所述

spring.datasource.url=jdbc:hsqldb:file:${project.basedir}/db/init

@membersound answer只是将硬编码路径分成两部分,而不是动态解析属性。我可以告诉您如何实现您想要的目标,但您需要了解的是,当您将应用程序作为jar或war运行时,没有project.basedir。在本地工作区之外,源代码结构不存在

如果您仍然希望为测试执行此操作,那么这是可行的,您需要的是操作
PropertySource
s。您最简单的选择如下:

定义一个
ApplicationContextInitializer
,并在那里设置属性。如下所示:

    public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext appCtx) {
        try {
            // should be /<path-to-projectBasedir>/build/classes/main/
            File pwd = new File(getClass().getResource("/").toURI());
            String projectDir = pwd.getParentFile().getParentFile().getParent();
            String conf = new File(projectDir, "db/init").getAbsolutePath();
            Map<String, Object> props = new HashMap<>();
            props.put("spring.datasource.url", conf);
            MapPropertySource mapPropertySource = new MapPropertySource("db-props", props);
            appCtx.getEnvironment().getPropertySources().addFirst(mapPropertySource);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }}
公共类MyApplicationContextInitializer实现ApplicationContextInitializer{
@凌驾
公共无效初始化(ConfigurableApplicationContext appCtx){
试一试{
//应为//build/classes/main/
File pwd=新文件(getClass().getResource(“/”.toURI());
字符串projectDir=pwd.getParentFile().getParentFile().getParent();
String conf=新文件(projectDir,“db/init”).getAbsolutePath();
Map props=newhashmap();
put(“spring.datasource.url”,conf);
MapPropertySource MapPropertySource=新的MapPropertySource(“db props”,props);
appCtx.getEnvironment().getPropertySources().addFirst(mapPropertySource);
}捕获(URISyntaxException e){
抛出新的运行时异常(e);
}
}}
看起来您正在使用Boot,所以您可以在
应用程序中声明
上下文.initializer.classes=com.example.MyApplicationContextInitializer
。properties
,Boot将在启动时运行此类

注意事项再次:

  • 这在本地工作区之外不起作用,因为它取决于源代码结构

  • 我在这里假设了一个Gradle项目结构
    /build/classes/main
    。如有必要,根据构建工具进行调整

  • 如果
    MyApplicationContextInitializer
    位于
    src/test/java
    中,
    pwd
    将是
    /build/classes/test/
    ,而不是
    /build/classes/main/


  • 我正在使用SpringBoot构建一个上载示例,遇到了同样的问题,我只想获得项目根路径。(例如/sring引导上载)

    我发现以下代码有效:

    upload.dir.location=${user.dir}\\uploadFolder
    

    ${project.basedir}在Spring containerReceive
    java.lang.IllegalArgumentException:无法解析字符串值“jdbc:hsqldb:file:${basedir}/db/init”
    中的占位符'basedir',所以在声明之前有一个名为
    basedir=…
    ?比它应该起的作用还大。当然,在重用placehodler之前必须声明它。这只是将硬编码路径分成两部分。OP寻找的是Boot可以解析的属性,而不是用户配置的属性。谁说上载文件夹将位于主目录下?@AbhijitSarkar我们对此有标准吗?任何资源都应该是项目的一部分
    upload.dir.location=${user.dir}\\uploadFolder