Spring Core/01. Overview

04. application 설정 파일 작성

  • -

스프링 부트에서는 application의 환경 설정을 위해서 src/main/resources 아래에 application.properties 또는 application.yml 파일을 사용할 수 있다. 이 둘은 동일한 내용을 약간 다른 방법으로 작성하는데 properties는 간단하지만 장황하고 yml은 상대적으로 복잡하지만 효율적이다.

 

.properties 작성 방법

 

key=value의 맵 구조

properties 파일은 key=value의 구조로 설정들을 작성한다. 여기서 많이 하는 실수 중 하나가 가독성을 높인다는 이유로 = 주변에 공백을 넣는 것이다. 그러면 공백까지 key 또는 value의 일부가 되버린다. 

!key는 'key' 속성의 값을 'value'이다.
key=value
!key는 'key ' 속성의 값은 ' value'이다.
key = value

한 줄 주석을 작성할 때는 # 또는 ! 를 사용한다. 이전에는 #을 주로 사용했는데 #--- 가 multi profile 표현으로 사용되면서 일반 주석은 ! 만 사용하는 편이 좋다.

key 값은 당연히 동일 문서에서 유일해야 하며 Map 구조의 객체를 표현할 때에는 .을 이용해서 계층을 표현할 수 있다.

! key=value 구조
ip=192.168.0.1
server.url=http://${ip}
server.user.id=hong
server.user.pass=1234
server.domain.name=com.doding

 

목록을 표현할 때는 한 줄에 여러 목록을 표시하거나 index를 이용해서 표현할 수 있다.

! String [] 또는 List<String>으로 처리
members.names=hong, jang, lim

! index 기반으로 하나씩 처리
members.skils[0]=java
members.skils[1]=spring
members.skils[2]=web
members.ages[0]=20
members.ages[1]=40

 

다중 문서 모드

하나의 문서에서 다중 profile을 처리하기 위해 다중 문서 모드를 사용할 수 있는데 이를 표현하기 위해 줄의 맨 앞에 #---을 사용한다. 이 경우 새로운 문서로 인식이 되고 동일한 key로 기존 속성을 재정의 할 수 있다. 

server.user.pass=1234
#---
! 이제 새로운 파일의 개념: 현재는 단순히 재정의
server.user.pass=5678

따라서 위의 설정이 있을 때 server.user.pass의 값은 1234가 아니라 5678이 된다.

 

단위테스트 작성

다음은 위 설정에 대한 테스트 코드이다.

SpringBoot와 JUnit을 쉽게 연동하기 위해서는 @SprintBootTest 애너테이션을 클래스 레벨에 사용한다. properties에 선언된 속성을 사용할 때에는 @Value에 사용할 속성의 정보를 ${속성_key} 형태로 작성해 준다. 

package com.doding.quickstart.quickstart;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class QuickstartApplicationTests {

	@Test
	void ipTest(@Value("${ip}") String ip) {
		assertEquals(ip, "192.168.0.1");
	}

	@Test
	void serviceTest(@Value("${server.url}") String url,
			@Value("${server.user.id}") String id,
			@Value("${server.domain.name}") String domain) {
		assertEquals(url, "http://192.168.0.1");
		assertEquals(id, "hong");
		assertEquals(domain, "com.doding");
	}

	@Test
	void listTest(@Value("${members.names}") List<String> names,
			@Value("${members.skils[0]}") String skil0,
			@Value("${members.ages[1]}") Integer age1) {
		assertEquals(names, List.of("hong", "jang", "lim"));
		assertEquals(skil0, "java");
		assertEquals(age1, 40);
	}

	@Test
	void multiDocTest(@Value("${server.user.pass}") String pass) {
		assertEquals(pass, "5678");
	}
}

 

yml 작성 방법

 

yml이란?

공홈에 보면 yml이란 " YAML Ain't Markup Language™ "라고 정체성을 밝히고 있는데 인간 친화적인 데이터 직렬화 도구로 모든 언어에서 동작한다고 되어있다.

https://yaml.org/

 

The Official YAML Web Site

 

yaml.org

주요 용도는 설정 파일을 만드는 데 있다. 설정 파일의 포맷이 xml -> json으로 넘어갔었는데 그 json의 개선판이 yml이다. 즉 yml은 JSON의 superset으로 valid 하게 만들어진 JSON의 확장자를 yml로 바꾸면 그냥 yml 파일이 된다.

yml은 properties에 비해 상당히 심오한 문법을 가지고 있긴 하다.

https://yaml.org/spec/1.2.2/#chapter-2-language-overview

 

YAML Ain’t Markup Language (YAML™) revision 1.2.2

 

yaml.org

하지만 다 살펴볼 필요는 없고 당장 쓸 것 위주로 알아보고 필요할 때 살을 붙이면 충분하다.

 

기본 표현법

  • 모든 속성 정보는 key: value의 map 구조를 갖는데 ':' 다음에는 무조건 공백 문자가 하나 와야 한다.
  • key는 문자열로 간주되며 하나의 문서에서 동일 레벨을 구성하는 key는 중복될 수 없다.
  • value에는 string, number, boolean 같은 기본형 뿐 아니라 객체(map 개념)도 사용 가능하며 목록(list)도 지원한다.
  • 주석을 표현할 때는 # 을 사용한다.
# key: value 구조
ip: 192.168.0.1

 

객체 속성의 표현

객체의 속성을 나타낼 때는 공백 들여 쓰기를 사용한다. 이때 공백의 개수는 상관없는데 문서 내에서 동일한 개수를 사용하는 것이 좋다. (통상 2개 또는 4개를 사용) 

다음은 server라는 키로 어떤 객체가 등록되어 있고 그 객체의 속성이 url, user 2개로 구성되어 있음을 보여준다. user는 다시 id와 pass 속성을 갖는다. 이미 선언된 다른 속성을 참조할 때에는 ${key}를 사용한다.

 
ip: 192.168.0.1
server:
  url: http://${ip}
  user:
    id: hong
    pass: 1234
  domain.name: com.doding
! key=value 구조
ip=192.168.0.1
server.url=http://${ip}
server.user.id=hong
server.user.pass=1234
server.domain.name=com.doding

properties 버전과 비교해 보면 계층적으로 표현하다 보니 코드의 중복이 감소하는 것을 볼 수 있다.

 

목록의 표현

목록을 나타낼 때는 ','를 이용해서 여러 개를 나열하며 프로그램에서 사용할 때는 배열 또는 List로 처리된다. 또는 [ ]를 이용해 묶어서 표현하거나 매 줄마다 - 를 이용해 요소를 나열하기도 하는데 이를 프로그램에서 사용할 때는 목록으로 받아서 사용하지 않고 인덱스를 이용해 개별 요소에 접근해야 한다.

members:
  #String [] 또는 List<String>으로 처리
  names: hong, jang, lim         
  #index 기반으로 하나씩 처리 
  skils: [java, spring, web]     
  ages:
    - 20
    - 40
! String [] 또는 List<String>으로 처리
members.names=hong, jang, lim
! index 기반으로 하나씩 처리
members.skils[0]=java
members.skils[1]=spring
members.skils[2]=web
members.ages[0]=20
members.ages[1]=40

 

다중 문서 모드

--- 를 통해서 다중 문서 모드로 사용할 수 있는데 이 경우 새로운 문서로 인식이 되고 동일한 key로 기존 속성을 재정의 할 수 있다. 이 속성을 이용해 나중에 다중 profile을 구성할 수 있다.

다음 예에서는 server.user.pass 속성을 처음에 1234라고 했다가 5678로 변경한 예이다.

server:
  user:
    pass: 1234
--- # 이제 새로운 파일의 개념: 현재는 단순히 재정의
server:
  user:
    pass: 5678
server.user.pass=1234
#---
! 이제 새로운 파일의 개념: 현재는 단순히 재정의
server.user.pass=5678

 

단위테스트 작성

설정 작성 방식이 단순히 properties에서 yml로 변경된 것이기 때문에 테스트 내용을 변경할 필요는 없다.

 

built in 속성의 활용

 

SpringBoot의 built in 속성들

위에서 선언했던 사용자 정의 속성들 외에도 SpringBoot에서는 기본적으로 제공되는 다양한 속성들이 있고 필요시 그 값을 재정의 해서 사용할 수 있다.

https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html

 

Common Application Properties

 

docs.spring.io

 

예를 들어 logging과 관련된 설정들을 살펴보자.

  • logging.level.* : logging.level은 Map 형태로 여러 개의 key: value를 받을 수 있다. key로는 log level을 설정할 package 이름이 들어오고 value에는 log의 level을 써주면 된다. 이 설정은 하위 package에까지 영향을 준다.
  • logging.pattern.console: 콘솔에 출력되는 로그의  pattern을 지정한다.
  • spring.output.ansi.enabled: ansi 형태로 출력되는 로그의 컬러 출력을 설정한다.

이처럼 필요에 따라 관련 속성을 찾아보고 재정의하는 형태로 사용하면 된다. 

위의 속성들을 테스트하기 위해 아래와 같이 간단히 로그를 출력하는 테스트를 만들어보자.

@Test
public void logTest() {
  log.trace("trace");
  log.debug("debug");
  log.info("info");
  log.warn("warn");
  log.error("error");
}

바로 테스트를 실행해보면 투박한 로그와 함께 info 이상의 정보만 출력되고 있다.

 

이제 로깅과 관련된 설정을 yml에 추가하고 다시 테스트를 실행해 보자.

logging:
  pattern:     # 콘솔에 출력되는 로그의 패턴 변경
    console: "%clr(%d{HH:mm:ss} [%-5p] %c{36}.%M.%L - %m%n)"
  level:       # com.doding의 하위 패키지에서 발생하는 로그는 debug 부터 출력
    com.doding: debug
    org.springframework: info
spring:
  output:
    ansi:
      enabled: always

이제 debug부터의 로그가 레벨에 따라 잘 구분되어 출력되고 있다.

properties에서는 다음과 같이 작성할 수 있다.

logging.pattern.console=%highlight(%d{HH:mm:ss} [%-5p] %c{36}.%M.%L - %m%n)
logging.level.com.doding=debug
logging.level.org.springframework=info
spring.output.ansi.enabled=always

 

관련 annotation

 

@PropertySource

추가해야할 설정들이 많아지면 하나의 설정 파일에 모든 내용을 담으면 복잡도가 올라간다. 이런 경우 별도의 설정 파일을 추가하고  @PropertySource에 등록해주면 된다. (application.properties 또는 application.yml 파일은 기본으로 등록된다.)

@Configuration
@PropertySource("classpath:customProperties.yml")
public class MyAppConfig {
    // 설정 내용
}

 

@TestPropertySource

application.properties와 application.yml 파일이 동시에 존재한다면 SpringBoot는 먼저 yml을 읽고 properties의 내용으로 덮어쓰게 된다. (물론 이런 것을 이용해서 프로그래밍하지는 않는다. 우선순위가 그렇다는 것)

SpringBoot에서는 테스트 과정에서 사용할 설정을 지정할 수 있는데 이때 사용되는 annotation으로 @TestPropertySource가 있다.

@SpringBootTest
@Slf4j
// 사용 대상(.yml or .properties)를 지정할 수 있다.
@TestPropertySource(properties = {"spring.config.location=classpath:application.yml" })
class QuickstartApplicationTests {
  // 테스트 코드 작성
}

https://inf.run/uTES7

 

참~쉬운 스프링 Part 1. 스프링 프레임워크 이해 및 DI,AOP 강의 | 모두의 코딩:두딩 - 인프런

모두의 코딩:두딩 | 스프링 프레임워크의 핵심을 파고드는 강의로, DI와 AOP를 비롯한 스프링의 중심 개념을 마스터하게 됩니다. 환경 설정부터 단위테스트, 로깅, 메이븐 사용법까지, 스프링 프

www.inflearn.com

 

 

'Spring Core > 01. Overview' 카테고리의 다른 글

03. SpringBoot를 위한 알쓸신잡  (0) 2023.11.21
02. 환경설정 및 Quick Start  (0) 2020.06.15
01. Spring Framework  (0) 2020.06.09
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.