application.yaml
resourceFolder: src/main/resources/properties
buildResourceFolder: build/resources/main/properties
yaml 파일
프로젝트폴더/src/main/resources/properties/data1.yaml
프로젝트폴더/src/main/resources/properties/data2.yaml
프로젝트폴더/src/main/resources/properties/data3.yaml
예제 클래스
package com.example.clova_ext.app.util.v3;
import lombok.Data;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ScheduledFuture;
@Slf4j
@Data
@Component
@RequiredArgsConstructor
public class YamlLoader implements ApplicationListener<ContextClosedEvent> {
private ScheduledFuture<?> task;
private final TaskScheduler taskScheduler;
private final Environment env;
// Resource 읽는 객체
private final PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver;
// 실제 데이터
@Getter
private HashMap<String, LinkedHashMap<String, Object>> properties = new HashMap<>();
// 파일명
private ArrayList<String> fileNames = new ArrayList<>();
// 최근 수정일
private Map<String, Long> modifiedMap = new HashMap<>();
private Map<String, Resource> resourceMap = new HashMap<>();
private Map<String, String> pathMap = new HashMap<>();
private boolean local;
public Map<String, Object> getProperties(String key) {
return properties.get(key + ".yaml");
}
//
// @Scheduled(cron = "0/5 * * * * * ")
// public void loadYaml() {
// fileNames.forEach(fileName -> {
// String path = pathMap.get(fileName);
// File file = new File(path);
//
// if (modifiedMap.get(fileName) < file.lastModified()) {
// try {
// modifiedMap.put(fileName, file.lastModified());
// FileInputStream io = new FileInputStream(file);
// properties.put(fileName, new Yaml().load(io));
// io.close();
// log.info("YamlLoader updated " + fileName);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// }
// });
// }
@EventListener(ApplicationReadyEvent.class)
private void applicationReadyEvent() throws IOException {
String tloFile = env.getProperty("tlo.file");
local = "tlo_local.properties".equals(tloFile);
log.info("tloFile={}", tloFile);
Resource[] resources = pathMatchingResourcePatternResolver.getResources("properties/*");
Arrays.stream(resources).forEach(resource -> {
try {
File file = resource.getFile();
String fileName = resource.getFilename();
String path = file.getAbsolutePath();
if (local) {
if (path.contains("/")) {
path = path.replace("/build/resources/main", "/src/main/resources");
} else {
path = path.replace("\\build\\resources\\main", "\\src\\main\\resources");
}
file = new File(path);
}
if (!fileNames.contains(fileName)) {
fileNames.add(fileName);
}
modifiedMap.put(fileName, file.lastModified());
pathMap.put(fileName, path);
FileInputStream io = new FileInputStream(file);
properties.put(fileName, new Yaml().load(io));
io.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
register();
}
public void register() {
Runnable runnable = () -> fileNames.forEach(fileName -> {
String path = pathMap.get(fileName);
File file = new File(path);
if (modifiedMap.get(fileName) < file.lastModified()) {
try {
modifiedMap.put(fileName, file.lastModified());
FileInputStream io = new FileInputStream(file);
properties.put(fileName, new Yaml().load(io));
io.close();
log.info("YamlLoader updated " + fileName);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
task = taskScheduler.scheduleAtFixedRate(runnable, 5000);
log.info("task.isCancelled()={}",task.isCancelled());
}
@Override
public void onApplicationEvent(ContextClosedEvent event) {
task.cancel(true);
}
}