스프링 부트 환경변수 설정하기

더보기

문제 상황

.yml 파일의 환경 변수 주입과 bean 과 환경 변수 주입 순서에대해 무지해 겪은 에러를 공유하고자 글을씁니다.

이번 프로젝트는 다음과 같은 환경에서 진행중입니다.

  • Java 11(JDK)
  • Spring Boot
  • Maven

위 환경에서 sms알림기능을 위해 API KEY와 저의 핸드폰 번호 등을 환경변수로 관리해야하는 상황이었습니다.

직접 구현하는건 처음이지만 익숙한 기능이기에 빠르게 할 수 있을 줄 알았습니다.. 

그러나 다음과 같은 두가지 문제가 발생했습니다.

  1. API_KEY, API_SECRET 환경 변수가 Null이다.
  2. (1번 해결후)제 휴대폰 번호가 아닌 다른 번호로 주입된다.

 

Bean 생성시기와 환경 변수 주입 시기

bean이란?

  • 기존 Java 에선 클래스를 생성하고 new를 입력하여 원하는 객체를 직접 생성한 후에 사용했으나
    Spring에선 IoC 컨테이너가 직접 객체를 생성하고 이를 Bean이라합니다.
  • Spring IoC 컨테이너가 관리하는 재사용 가능한 객체 입니다.

 

저는 다음과 같이 bean을 등록했었습니다.

@Service
@RequiredArgsConstructor
public class NotificationServiceImpl implements NotificationService{

    @Value("${sms.api.key}")
    private String API_KEY;

    @Value("${sms.api.secret}")
    private String API_SECRET;

    @Value("${sms.api.send.number}")
    private String SEND_NUM;


    private final DefaultMessageService messageService = NurigoApp.INSTANCE.initialize(API_KEY, API_SECRET, "https://api.coolsms.co.kr");
    
    //.....
}

 

Spring Boot에선 @RequiredArgsConstructor 어노테이션을 이용해 자동으로 (final 제한자를 사용한 경우) 의존성 주입이 가능합니다.

그런데 파라미터로 사용된 API_KEY에서 NullPointerException 에러가 발생했습니다. 그 이유는 Spring Boot는 Bean 등록 이후 환경변수를 할당하기 때문입니다. 즉,  messageService의 Bean을 등록하는 시점에 환경변수가 할당 되지 않았기 때문이었습니다.

 

이후 바뀐 코드는 다음과 같습니다.

 

@Service
@RequiredArgsConstructor
public class NotificationServiceImpl implements NotificationService{

    @Value("${sms.api.key}")
    private String API_KEY;

    @Value("${sms.api.secret}")
    private String API_SECRET;

    @Value("${sms.api.send.number}")
    private String SEND_NUM;


    private DefaultMessageService messageService;

    @PostConstruct
    public void init() {
        this.messageService = NurigoApp.INSTANCE.initialize(API_KEY, API_SECRET, "https://api.coolsms.co.kr");
    }

}

 

위 처럼 바꿔주어 @PostConstruct를 사용하여 의존성 주입 단계 이후에 해당 코드를 실행 할 수 있게 조치하였습니다. 이후 잘 동작할줄 알았으나.. 제 번호를 저장하는 변수인 SEND_NUM이 엉뚱한 수를 가지는것 오류가 있었습니다.

 

.yml 의 환경 변수 주입 과정

결론부터 말하자면 .yml 파일은 휴대폰 번호처럼 0으로 시작하고 숫자로되며 8미만의 숫자가 있는 변수는 8진수로해석합니다.

 

예를들어 다음과 같은 설정인 경우 해당합니다.

이 경우 01012341234를 8진수로 인식하고 이를 10진수로 바꾼 값이 저장됩니다.

따라서 " " 를 붙여 다음과 같이 변경시 의도대로 값이 저장되는걸 확인할 수 있습니다.

 

마침 제 번호도 8이상의 수가 없어 엉뚱해 보이는 수가 계속 출력되었고 다른 팀원의 번호는 해당하지 않아 " "없이도 정상적으로 출력되는 상황에 많이 당황스러웠네요..!