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

时间:2018-12-13 13:01:23

标签: java spring tomcat javabeans properties-file

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

以下PoC类别:

var builder = new NpgsqlConnectionStringBuilder();
//setting connection string variables here
var connection = new NpgsqlConnection(builder.Tostring());
var query = "SELECT * FROM \"TableName\" ORDER BY \"ColumnName\"";
var adapter = new NpgsqlDataAdapter(query, connection);
var dataSet = new DataSet();

connection.Open();
adapter.Fill(dataSet);

服务属性

@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());
    }
}

ServiceOutputProperties

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

控制器

@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;
    }
}

application.properties

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

    @Autowired
    private ServiceOutput serviceOutput;

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

}

放入Catalina文件中的XML文件

prefix.param=2

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

在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您可以使用Spring Cloud的刷新作用域功能来实现它,请考虑大小写:

@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请求(如果使用的是弹簧执行器)或注入RefreshScope bean并调用refreshAll()方法(如果要刷新单个bean,则为refresh(String name)

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

spring-cloud-context中包含刷新范围功能,因此我相信它足够可靠