Spring boot @PropertySource로 yml 로드 방법
안녕하세요. 오늘은 @PropertySource를 통해 yml파일을 로드하는 방법을 알려드리고자 합니다.
프로젝트를 진행하면서 카카오,네이버에서 제공하는 API를 호출할때 필요한 secret key를 property파일로 분리 한 후 Bean,Configuration으로 등록하여 호출 시 해당 secrey key를 API 호출 시 실어 사용하는 경우가 많았습니다. 이때 많은 사람들이 yml를 사용하지 않고 properties를 사용하는데 저는 yml를 사용하고 하고 싶어서 찾아낸 방법을 공유하고자 합니다. 그러면 우선 @PropertySource를 알아야 할 것 같습니다.
@PropertySource
@PropertySource는 기본적으로 설정파일을 읽어 속성을 주입하는 기능을 담당합니다.
간단한 예시를 아래와 같은 구조로 구성했습니다.
naver.properties
naver.name=pooney
naver.secretKey=pooney-secret
NaverConfig.class
@Configuration
@ConfigurationProperties(prefix = "naver") //naver로 시작하는 것을 찾습니다.
@PropertySource(value = {"naver.properties"}) // classpath로 부터 경로가 시작되고 naver.properties를 읽습니다.
@Getter
@Setter
@ToString
public class NaverConfig {
private String secretKey; //naver.properties에 등록한 secretKey를 binding
private String name; //naver.properties에 등록한 name를 binding
}
NaverConroller.class
@RequestMapping("naver")
@RequiredArgsConstructor
@RestController
public class NaverContoller {
private static final Logger logger = LoggerFactory.getLogger(NaverContoller.class);
private final NaverConfig naverConfig;
@GetMapping("/short_url")
public ResponseEntity<String> getShortUrl(){
logger.info("[naverConfig] : "+ naverConfig);
return new ResponseEntity<>("naverConfig", HttpStatus.OK);
}
}
해당 short_urlf를 호출 할때 "[naverConfig]" 라는 로그는 어떤 값을 출력 할까요?
[naverConfig] : NaverConfig(secretKey=pooney-secret, name=pooney)
바로 위와 같이 제가 properties에 설정한 값이 출력됩니다. 즉 @PropertySource는 해당 위치에 있는 properties를 읽어 내가 만든 class의 변수에 binding 시켜주는 아주 편리한 기능을 담당하고 있습니다.
그러면 properties 파일이 아닌 yml를 읽어 사용하고 싶은경우에는 확장자를 yml로 바꿔서 사용하면 될까요....?
@PropertySource는 기본적으로 yml을 로드하지 않습니다..
그러면 yml을 읽을 수 있는 방법을 없을까요? 아닙니다. PropertySourceFactory라는 별도의 사용자 정의를 통해 로드 할 수 있습니다.
PropertySourceFactory
yml을 읽을 수 있게 도와주는 PropertySourceFactory의 구현체인 YamlLoadFactory를 통해 해결 할 수 있습니다.
YamlLoadFactory.class
public class YamlLoadFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource)
throws IOException {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());
Properties properties = factory.getObject();
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
}
}
naver.yml
naver:
name: pooney
secretKey: pooney-secret
NaverConfig.class
@Configuration
@ConfigurationProperties(prefix = "naver")
@PropertySource(value = {"naver.yml"}, factory = YamlLoadFactory.class) // 위에 만든 factory를 넣어줍니다.
@Getter
@Setter
@ToString
public class NaverConfig {
private String secretKey;
private String name;
}
NaverConroller.class
@RequestMapping("naver")
@RequiredArgsConstructor
@RestController
public class NaverContoller {
private static final Logger logger = LoggerFactory.getLogger(NaverContoller.class);
private final NaverConfig naverConfig;
@GetMapping("/short_url")
public ResponseEntity<String> getShortUrl(){
logger.info("[naverConfig] : "+ naverConfig);
return new ResponseEntity<>("naverConfig", HttpStatus.OK);
}
}
결과물은 properties와 동일하게 출력되는 것을 확인 할 수 있습니다.
[naverConfig] : NaverConfig(secretKey=pooney-secret, name=pooney)
yml를 propertis처럼 동일하게 로드하여 configuration으로 등록하기위 많은 시도와 검색결과를 통해 얻은 내용입니다.
프로젝트에서 유용하게 사용 할 수 있으니 많이들 익혀주세요.