Spring 에서 application.properties 값을 객체에 저장하는 2가지 방법

application.properties

// application.properties
test.message=this is a message.
test.city=city is Seoul

@Value

How to use?

  • @Value 애노테이션을 활용하여 프로퍼티의 값을 받아올 수 있다.
  • 사용방법은 다음과 같다.
// TestController.java
@RestController
public class TestController {

    @Value("${test.message}")
    private String message;

    @Value("${test.city}")
    private String city;

    @GetMapping("/test")
    public String test() {
        return message + " / " + city;
    }
}

결과

장단점

  • @Value 애노테이션은 사용하기 간단하지만, 공통으로 묶어야할 프로퍼티가 많아질 경우 코드가 지저분해진다.
  • 프로퍼티의 값들을 스프링 빈의 필드로 매핑하여 사용할 수 있는 애노테이션이 @ConfigurationProperteis 이다.

@ConfigurationProperties

How to use?

// PropertiesConfig.java
@Configuration
@EnableConfigurationProperties(value = TestProperties.class)
public class PropertiesConfig {

}
  • 먼저 프로퍼티관련 설정파일을 만들어줘야 한다.
  • @Configuration 애노테이션으로 설정파일임을 스프링에 등록하고
  • @EnableConfigurationProperties 애노테이션에 설정할 프로퍼티 클래스를 등록한다.
    • value 가 배열타입이기 때문에 여러개의 프로퍼티를 등록할 수 있다. 이곳에 설정된 클래스는 스프링 빈으로 등록되어 이후 다른 빈에서 DI를 통해 주입받아 사용할 수 있다.
  • 이후 실제 값을 매핑할 TestProperties 를 만든다.
// TestProperties.java
// Setter 방식
@ConfigurationProperties(prefix = "test")
public class TestProperties {

    private String message;
    private String city;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}
// TestProperties.java
// 생성자 주입 방식
@ConfigurationProperties(prefix = "test")
@ConstructorBinding
public class TestProperties {

    private final String message;
    private final String city;

    public TestProperties(String message, String city) {
        this.message = message;
        this.city = city;
    }

    public String getMessage() {
        return message;
    }

    public String getCity() {
        return city;
    }
}
  • @ConfigurationProperties 애노테이션을 사용하여 프로퍼티파일의 값을 스프링 빈의 필드와 매핑할 수 있다. prefix 에 프로퍼티 prefix를 등록한다.
  • 프로퍼티 파일에 있는 키값과 동일한 이름의 필드를 만든다.
  • 프로퍼티 클래스는 application.properties 로부터 Setter 방식과 Constructor 2가지 방식으로 프로퍼티값을 주입받을 수 있다.
  • Setter 방식은 생성이후 값의 변경이 가능하기 때문에 추천하지 않는다고 한다.
  • 생성자 주입방식을 사용할 경우 @ConstructorBinding 애노테이션을 붙여줘야한다.
  • 다른곳에서 주입받아 사용할 때 값을 받아올수 있게 Getter 를 만들어준다.

참고로, properties가 아닌 yml로 작성해도 동일하게 작동한다.
또한 properties 파일에서는 보통 camelCase보다 kebab-case(단어를 - 로 연결) 하는 형태를 자주 사용하는데 @ConfigurationProperties를 통해 자바 객체로 바인딩 될때는 카멜케이스로 자동으로 변경이 되기 때문에 프로퍼티 파일에 케밥케이스를 사용했다 하더라도 자바파일에서는 자바 코드 컨벤션인 카멜케이스를 그대로 사용하면 된다.

@Value 애노테이션에서는 문자형태를 그대로 지켜줘야 값을 받아온다.

// TestController.java
@RestController
public class TestController {

    private final TestProperties testProperties;

    public TestController(TestProperties testProperties) {
        this.testProperties = testProperties;
    }

    @GetMapping("/test")
    public String test() {
        return testProperties.getMessage() + " / " + testProperties.getCity();
    }
}
  • 생성자나 @Autowired 를 활용하여 프로퍼티 빈을 주입받고 Getter 를 사용해서 값을 받아오면 된다.

결과

장단점

  • 설정관련한 파일이 @Value 애노테이션을 사용할떄보다 많아진다.
  • 공통으로 묶어야할 프로퍼티 값이 많아진다면 (test.xxx, test.yyy...) @ConfigurationProperties 를 활용하는 방법이 더 좋을 것 같다.

번외

properties 값을 static 변수에 등록

@Component
public class TestProperties2 {

    public static String message;

    @Value("${test.message}")
    public void setMessage(String message) {
        TestProperties2.message = message;
    }
}
@RestController
public class TestController {

    @GetMapping("/test")
    public String test() {
        return TestProperties2.message;
    }
}
  • 위와 같이 사용은 가능하지만 Setter 주입방식과 마찬가지로 추천하지 않는다고 한다.

참고링크
https://stackoverflow.com/questions/7253694/spring-how-to-inject-a-value-to-static-field

좋은 웹페이지 즐겨찾기