보통 Java에서 상수 값은 코드적으로 Enum이나 private final static으로 관리를 할 것이다.
하지만 Spring에서는 .properties 나 .yml 확장자 설정 파일들을 관리할 수 있도록 도와준다.
이번에는 .properites 또는 .yml 에 있는 값들을 소스 코드에 주입해서 사용하는 방식에 대해 알아보겠다.
소스코드에 주입하는 방식은 3가지 있다.
- component 등록+ConfigurationProperties + getter + setter 주입 방식
- component 등록 + @Value 주입 방식
- ConstructBinding + ConfigurationProperties + 외부 클래스에 configuration + EnableConfigurationProperties(${ConstructBinding을 받는 클래스})
문제점
- 첫번째 방식은 getter 뿐만 아니라 setter도 열려있어 변경에 대한 여지가 열려있게 된다.
- 해당 prefix가 중복이 발생한다.
결국 2개 모두 불변성에 대해 문제가 있다.
final 한 필드로 인스턴스 변수를 생성할 수 없기 때문이다.
💨What
final 키워드를 사용하여 최초 초기화를 보장하며 불변을 유지할 수 있는 property 주입 방식
❓Why
- 불변 객체는 외부에서 가져온다 한들 변경에 대해 막혀 있어 버그 또는 이슈가 발생할 수 있는 여지가 줄어든다.
- 특히나 생성자 전략은 객체 생성시 최초 초기화 1번을 보장하는 방식이므로 안전하기 때문이다.
✅How
- component 등록+ConfigurationProperties + getter + setter 주입 방식
@Component @ConfigurationProperties(prefix = "personal") class TestConfigInjection { private String value; public void setValue(String value) { this.value = value; } public String getValue() { return value; } }
- component 등록 + @Value 주입 방식
@Component class PropTestConfig { @Value("${personal.value}") private String value; public String getValue() { return value; } }
- ConstructBinding + ConfigurationProperties + 외부 클래스에 configuration + EnableConfigurationProperties(${ConstructBinding을 받는 클래스})
// 선언 방식 @Autowired private CreatorTest ct; @ConstructorBinding @ConfigurationProperties(prefix = "personal") class CreatorTest { private String value; public void setValue(String value) { this.value = value; } public String getValue() { return value; } } @Configuration @EnableConfigurationProperties({CreatorTest.class}) class ConsConfig{ }