[TIL] @ConfigurationProperties

phdljr·2023년 12월 21일
0

TIL

목록 보기
47/70

Redis나 JavaMailSender를 사용해봤다면, 설정 값들을 application파일에 선언해둔 적이 있을 것이다.

  data:
    redis:
      host: localhost
      port: 6379

  mail:
    host: smtp.gmail.com
    port: 587
    username: ...
    password: ...
    properties:
      smtp:
        auth: true
        starttls:
          enable: true

외부 파일에 설정해둔 값들을 스프링에서 읽으려면 @Value 를 통해 읽어왔었다.

@Configuration
public class MailConfig {

    @Value("${spring.mail.host}")
    private String host;

    @Value("${spring.mail.port}")
    private int port;

    @Value("${spring.mail.username}")
    private String username;

    @Value("${spring.mail.password}")
    private String password;

    @Value("${spring.mail.properties.smtp.auth}")
    private boolean auth;

    @Value("${spring.mail.properties.smtp.starttls.enable}")
    private boolean starttlsEnable;
}

하지만, 이는 하나의 속성값만 읽어올 수 있어서 번거로움이 존재한다.

이러한 값들을 편하게 읽어올 수 있는 기능을 가진 @ConfigurationProperties에 대해 살펴보는 시간을 가져보겠다.


@ConfigurationProperties

  • 설정 파일에 적힌 설정값들을 쉽게 읽어올 수 있게 제공해주는 어노테이션

설정

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.0</version>
    <relativePath/>
</parent>

예제 코드

기본 사용

mail.hostname=host@mail.com
mail.port=9000
mail.from=mailer@mail.com
  • 다음과 같은 속성 값들을 읽어오는 모습을 볼 수 있다.
  • 속성 값을 읽어올 클래스는 반드시 빈으로 등록이 돼있어야 한다.
  • 기본적으로 setter가 존재해야 된다.
@Configuration
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {
    
    private String hostName;
    private int port;
    private String from;

    // standard getters and setters
}
  • setter가 싫다면, @ConstructorBinding을 사용해서 생성자를 통해 바인딩하면 된다.
  • 생성자가 여러개라면, 사용할 생성자에 달아주면 된다.
@ConfigurationProperties(prefix = "mail")
@ConstructorBinding
public class ConfigProperties {
    
    private String hostName;
    private int port;
    private String from;
	
    public ConfigPropertiest(String hostName, int port, String from){
    	this.hostName = hostName;
        this.port = port;
        this.from = from;
    }
}
  • 그러나, @Configuration을 달지 못한다.
  • 다른 곳에서 @EnableConfigurationProperties@ConfigurationPropertiesScan를 통해 해당 클래스를 등록시켜줘야 한다.
@SpringBootApplication
@ConfigurationPropertiesScan("com.baeldung.configurationproperties")
public class EnableConfigurationDemoApplication { 

    public static void main(String[] args) {   
        SpringApplication.run(EnableConfigurationDemoApplication.class, args); 
    } 
}
  • 또한, 속성 값들을 읽기 위한 네이밍 규칙이 존재한다.
mail.hostName
mail.hostname
mail.host_name
mail.host-name
mail.HOST_NAME
  • 위의 어느 경우라도 private String hostName 과 바인딩된다.

중첩된 속성 값 읽기

#Simple properties
mail.hostname=mailer@mail.com
mail.port=9000
mail.from=mailer@mail.com

#List properties
mail.defaultRecipients[0]=admin@mail.com
mail.defaultRecipients[1]=owner@mail.com

#Map Properties
mail.additionalHeaders.redelivery=true
mail.additionalHeaders.secure=true

#Object properties
mail.credentials.username=john
mail.credentials.password=password
mail.credentials.authMethod=SHA1
public class Credentials {
    private String authMethod;
    private String username;
    private String password;

    // standard getters and setters
}

public class ConfigProperties {

    private String hostname;
    private int port;
    private String from;
    private List<String> defaultRecipients;
    private Map<String, String> additionalHeaders;
    private Credentials credentials;
 
    // standard getters and setters
}

@Bean 메소드에 바로 적용

public class Item {
    private String name;
    private int size;

    // standard getters and setters
}

@Configuration
public class ConfigProperties {

    @Bean
    @ConfigurationProperties(prefix = "item")
    public Item item() {
        return new Item();
    }
}

Property Validation 적용 가능

  • JSR-380 형식을 지원한다.
public class Item {
	@NotBlank
    private String name;
    
    @Min(10)
    @Max(2100)
    private int size;

    // standard getters and setters
}

record에 적용

@ConstructorBinding
@ConfigurationProperties(prefix = "mail.credentials")
public record ImmutableCredentials(String authMethod, String username, String password) {
}

참조

https://www.baeldung.com/configuration-properties-in-spring-boot

profile
난 Java도 좋고, 다른 것들도 좋아

0개의 댓글