我已经了解了如何在运行时更新外部属性,但是我认为它可以改进,并且不确定可能的错误,因为我可能会遗漏。
首先,我将文件中的外部位置设置为vm,将其设置为-Dspring.config.location
,并将其设置为vm。然后进入具有该位置值的呼叫服务:
json.properties.location = /project/properties/data.json
在这里,我读取了文件并创建了包含它的内容的对象,如果已经创建了对象列表,则什么也不做,还有一种刷新方法,该方法只调用list的clear方法。
然后我有了观察程序组件:
@Service
public class DataService {
@Value("${json.properties.location}")
private String purposeFile;
static List<WireTransferPurpose> purposeList = new HashMap<>();
private static void generateData(String filePath) {
// Initialize the purpose list
if (purposeList.isEmpty()) {
// create the path with the file location
Path path = Paths.get(filePath);
StringBuilder data = new StringBuilder();
try(Stream<String> lines = Files.lines(path)) {
lines.forEach(line -> data.append(line).append("\n"));
}
catch (Exception e) {
throw new PropertiesFilesNotFoundException("Error reading the properties file.");
}
// maps JSON file content to the indicated object
Type mapType = new TypeToken<List<WireTransferPurpose>>() {
private static final long serialVersionUID = -2457565451021504055L;
}.getType();
try {
purposeList = new Gson().fromJson(data.toString().trim(), mapType);
}
catch (Exception e) {
throw new NotValidPorpertiesDataException();
}
}
}
public static void refreshProperties() {
purposeList.clear();
}
private List<WireTransferPurpose> purposeList( {
generateData(purposeFile);
return purposeList;
}
}
最后一步是在某个地方运行服务,这是我有更多疑问的地方,我将其放置在主要的Spring Boot应用程序类中,主要是为了使用静态方法:
@Configuration
public class PropertiesWatcher {
private static final String PROPERTIES_LOCATION = "\\project\\properties";
public static void refreshService() throws IOException, InterruptedException {
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get(PROPERTIES_LOCATION);
path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
DataService.refreshProperties();
}
}
key.reset();
}
}
}
答案 0 :(得分:1)
您可以看看MBeans。
MBean是类似于JavaBeans组件的托管Java对象,它遵循JMX规范中阐述的设计模式。 MBean可以代表设备,应用程序或任何需要管理的资源。
由于您使用的是Spring,因此您可以执行以下操作:
@Component
@ManagedResource(objectName = com.whatever:name=Configurator",
description = "Whatever JMX Configurator")
public class WhateverJMXBean {
private final Configurator configurator;
public WhateverJMXBean(final Configurator configurator){
this.configurator = configurator;
}
@ManagedAttribute
public void setField(String field) {
configurator.setField(field);
}
@ManagedAttribute
public String getField() {
return configurator.getField();
}
}
Configurator类是属性的处理程序,基本上是POJO:
@Data
@Configuration
public class Configurator{
private String field;
public void setField(String field){
this.field = field;
}
public String getField(){
return this.field;
}
}
您将能够从JConsole
设置和查询属性。