pooney

 

 

 

 

 

 

안녕하세요. 오늘은 @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으로 등록하기위 많은 시도와 검색결과를 통해 얻은 내용입니다. 

 

프로젝트에서 유용하게 사용 할 수 있으니 많이들 익혀주세요. 

 

 

 

 

 

 

 

 

 

 

https://www.baeldung.com/spring-yaml-propertysource

profile

pooney

@pooney

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!