如何在不属于 jar 的运行时重新加载 application.properties

How to reload application.properties in runtime which is not part of jar

我的 application.properties 文件有问题,它不属于我的 war 文件。我想创建一个可以在运行时更改 application.properties 值的应用程序。我的属性文件将是我们将在服务中使用的 bean。

类 以下 PoC:

@Configuration
@Slf4j
public class ServiceReaderConfiguration {
    @Bean
    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    ServiceOutputProperties serviceProperties() {
        log.info("create serviceProperties");
        return new ServiceOutputProperties();
    }

    @Bean
    ServiceOutput serviceOutput() {
        log.info("create serviceOutput");
        return new ServiceOutput(serviceProperties());
    }
}

服务属性

@Configuration
@ConfigurationProperties(prefix = "prefix")
@Setter
@Getter
public class ServiceOutputProperties {
    private int param;
}

ServiceOutputProperties

@Slf4j
public class ServiceOutput {

    private ServiceOutputProperties serviceOutputProperties;

    public ServiceOutput(ServiceOutputProperties serviceOutputProperties) {
        log.info("creating serviceOutputProperties");
        this.serviceOutputProperties = serviceOutputProperties;
    }

    public int printValueFromFile() {
        int param = serviceOutputProperties.getParam();
        return param;
    }
}

控制器

@RestController
@RequestMapping("/api")
public class ControllerConfiguration {

    @Autowired
    private ServiceOutput serviceOutput;

    @GetMapping("/print")
    public ResponseEntity<Integer> postValueFromPropertiesFile() {
        return ResponseEntity.ok(serviceOutput.printValueFromFile());
    }

}

application.properties

prefix.param=2

XML 文件放入 Catalina 文件

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Environment name="spring.config.location"
value="file:/home/marcin/tomcat/application.properties"
type="java.lang.String"/>
</Context>

我正在构建 war 没有应用程序的包 属性 我想在运行时修改的文件。包正在 tomcat 上部署。我想要实现的是修改属性文件并在运行时使用控制器显示文件中的更改值,而无需重新加载应用程序。

在此先感谢您的帮助。

您可以使用来自 spring 云的刷新范围功能来实现它,考虑案例:

@ConfigurationProperties(prefix = "prefix")
@PropertySource("path to properties file, you can inject it as property ${spring.config.location}")
@RefreshScope
public class ServiceOutputProperties {
  private int param;

//getters & setters
}

稍后您可以通过两种方式像这样刷新 bean:通过向端点 /actuator/refresh 发送 POST 请求(如果您使用的是 spring-actuator)或通过注入 RefreshScope bean 并调用 refreshAll() 方法(或者 refresh(String name) 如果你想刷新单个 bean)。

您可以使用 WatchService API 创建侦听器,它会在每次文件修改时调用上述方法之一。

刷新范围功能包含在 spring-cloud-context 中,所以我相信它足够轻