[Spring Boot] 스프링 @Value 어노테이션으로 properties 값 읽어오기
- 웹 개발/Spring Boot
- 2020. 1. 7. 14:54
필자는 인텔리제이라는 IDE를 사용합니다. 대략 2-3개월정도 되었는데요.
이클립스로 개발할 때는 주로 스프링 레거시 프로젝트로 프로그래밍을 하곤 하였는데,
인텔리제이로 갈아타면서 스프링부트를 접하게 되었습니다.
프로젝트를 생성하고 나니 resources 폴더 밑에 application.properties 파일이 자동적으로 생성이 되어 있더라구요.
이 파일은 스프링부트에서 Configuration을 잡을 때 대체할 문자/숫자 데이터를 적어 두고 추후에 활용하는 파일입니다.
예를 들어, 디비정보, 앱 버전정보, 에러설정정보, 포트정보 등입니다.
뭐 이러한 것들은 실제 Config 자바 파일에서도 설정이 가능한 부분이 존재합니다. 일부는 스프링부트에서 글로벌 변수처럼 등록해서 활용하는 것들도 있구요(ex/ server.port)
그런데 커스터마이징할 설정정보들은 소스코드에 그냥 쓰면되는데 왜 굳이 properties파일을 사용할까???
예제를 살펴보고 난 후 정리해보겠습니다.
application.properties 파일에 등록한 User 클래스 정보를 읽어 toString() 메소드로 확인하는 예제
- application.properties
custom.myname=blackdog
custom.myage=10
custom.mytel=01000001122
- User 클래스
package com.tutorial.springboottutorial;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class User {
@Value("${custom.myname}")
private String name;
@Value("${custom.myage}")
private int age;
@Value("${custom.mytel}")
private String tel;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", tel='" + tel + '\'' +
'}';
}
}
* 주의할 점 : 처음에 @Component를 몰래 빼먹고... 돌려봤는데 계속 null이 뜨길래... 일단 스프링의 bean으로 등록해야 @Autowired로 의존주입할때 Null객체가 되는일이 없습니다.
- 테스트코드
package com.tutorial.springboottutorial;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootTutorialApplicationTests {
@Autowired
User user;
@Test
void contextLoads() {
}
@Test
public void userTest(){
System.out.println(user.toString());
System.out.println(new User().toString());
}
}
결과
User{name='blackdog', age=10, tel='01000001122'}
User{name='null', age=0, tel='null'}
아래 User객체는 스프링의 빈으로 등록된 인스턴스가 아니기때문에 @Value 어노테이션이 작동하지 않은 것을 볼수있습니다.
실제로 스프링 컨테이너 내부에서는 빈들을 모두 등록할 때 @Value() 안의 내용에 맞는 값을 application.properties에서 찾아 넣어주게 됩니다.
그런데 위의 application.properties 파일의
custom.myname=코딩하는흑구
로 변경해서 돌려본다면 인코딩이 깨지는 모습을 볼 수 있을 것입니다.
결과 : User{name='ì½ë©íëí구', age=10, tel='01000001122'}
한글 인코딩 깨짐 해결방법
- 이는 유니코드로 해결할 수 있습니다. properties파일에 한글을 등록하고 싶다면 아래와 같이 한글을 유니코드로 변환하여 properties에 기재해놔야 합니다.
custom.myname=\uCF54\uB529\uD558\uB294\uD751\uAD6C
- 한글 <-> 유니코드 간의 변환 주소 : https://sas-study.tistory.com/272
왜 굳이 properties파일을 사용할까???
개인적으로 생각해본바 배포하고난 후의 설정을 변경할때 서버를 내리지 않고 변경해주기 위함이 주가 아닐가 싶습니다.
예를들어, 자바 소스코드에서 설정정보를 관리한다면 설정정보가 든 클래스를 컴파일러가 컴파일하여 자바 바이트코드로 반환하고 이를 JVM이 실행하고 클래스가 모두 로딩되고나서야 비로소 해당 정보들이 머신에게 의미있는 정보가 될텐데요. 가령 포트하나만 변경해야하는 작은 작업단위일때조차 서버 셧다운을 쳐야하는 비용이 소모되는 것입니다.
하지만 properties 파일로 관리되는 정보들을 불러다 쓰는 것은 조금 다릅니다. 키-값 구조로 정의된 값들이 소스코드에서는 키만 불러다가 값으로 치환되는 작업을 거칠텐데요. 이는 소스코드를 수정해야할 필요도 없을 뿐만아니라 서버에 접속해서 properties 파일만 수정하고 끝나면 되는 것이기 때문에 배포가 완료된 이후 과정에서는 매우 편리해 보입니다.(포트변경을 예로 든것은 간단한 작업의 예시입니다.)
이 당시의 코딩하는 흑구는 이렇게 생각했다!