메이븐(Maven)은 설정 파일인 pom.xml이 XML 기반으로 구성되어 있어 동적인 행위에 제약이 있다.
그래들은 앤트(Ant)의 기본적인 빌드 도구의 기능과 Maven의 의존 라이브러리 관리 기능을 합친 것으로, JVM에서 동작하는 스크립트 언어 그루비(Groovy) 기반의 DSL(Domain Specific Language)를 사용한다.
멀티 프로젝트 구성 시 메이븐처럼 상속 구조가 아닌 설정 주입 방식을 이용하여 훨씬 유연하게 빌드 환경을 구성할 수 있다.
스프링 부트는 프로젝트 첫 설정 시 그래들 래퍼 관련 설정을 자동으로 해준다.
그래들 멀티 프로젝트를 활용하면 여러 프로젝트를 마치 하나의 프로젝트처럼 사용할 수 있다.
공통 코드를 하나의 프로젝트로 분리하고 이를 재사용할 때 유용한 기능이다.
ex) 웹, API, 배치 세 프로젝트 모두에서 사용하는 공통 도메인의 변경이 있을 경우 모든 프로젝트에서 일일이 수정해주는 번거로움을 줄일 수 있다.
스프링 부트 프로퍼티 파일은 설정 관련 및 기타 정적인 값을 키값 형식으로 관리하기 때문에 스프링 프레임워크의 복잡한 XML 설정을 파일 하나로 설정할 수 있다.
YAML은 원래 'Yet Another Markup Language(또 다른 언어)' 라는 뜻이었지만, YAML의 핵심은 문서 마크업이 아닌 데이터 중심에 있다는 것을 보여주기 위해 이름을 바꾸었다고 한다.
가독성이 좋으며 문법이 이해하기 수월하도록 작성된 언어이다. JSON도 YAML의 일종이다.
실제 서비스 개발 시 로컬 DB, 개발 DB, 운영 DB의 설정값이 모두 다른데, 이런 경우를 대비하여 프로파일에 따라 프로퍼티를 다르게 설정해야 한다.
server:
port: 80
---
spring:
profiles: local
server:
port: 8080
---
spring:
profiles: dev
server:
port: 8081
YAML 파일을 사용하면 List, Set, Map 등 다양한 바인딩형 매핑이 간편하다.
property:
test:
name: property depth test
propertyTest: test
propertyTestList: a, b, c
@SpringBootTest(classes = SpringBootCommunityWebApplicationTests.class)
@RunWith(SpringRunner.class)
public class valueTest {
// 깊이가 존재하는 키값에 대해 '.'로 구분하여 값 매핑
@Value("${property.test.name}")
private String propertyTestName;
// 단일 키값 매핑
@Value("${propertyTest}")
private String propertyTest;
// YAML 파일에 키값이 존재하지 않으면 디폴트값이 매핑되도록 설정
@Value("${noKey:default value}")
private String defaultValue;
// 여러 값을 나열할 때 배열형으로 매핑
@Value("${propertyTestList}")
private String[] propertyTestArray;
// spEL을 사용하여 ','를 기준으로 List에 매핑
@Value("#{'${propertyTestList}'.split(',')}")
private List<String> propertyTestList;
@Test
public void testValue() {
assertThat(propertyTestName, is("property depth test"));
assertThat(propertyTest, is("test"));
assertThat(defaultValue, is("default value"));
assertThat(propertyTestArray[0], is("a"));
assertThat(propertyTestArray[1], is("b"));
assertThat(propertyTestArray[2], is("c"));
assertThat(propertyTestList.get(0), is("a"));
assertThat(propertyTestList.get(1), is("b"));
assertThat(propertyTestList.get(2), is("c"));
}
}
fruit:
list:
- name: banana
color: yellow
- name: apple
color: red
- name: water melon
color: green
@Data
@Component // 의존성 주입을 위해 선언
@ConfigurationProperties("fruit")
public class FruitProperty {
private List<Map> list;
}
application.yml이 아닌 다른 이름의 YAML 파일로 관리할 때는 @ConfigurationProperties(prefix = "fruit")
로 사용한다.
@RunWith(SpringRunner.class)
@SpringBootTest
public class ConfigurationPropertiesTest {
@Autowired
FruitProperty fruitProperty;
@Test
public void test() {
List<Map> fruitData = fruitProperty.getList();
assertThat(fruitData.get(0).get("name"), is("banana"));
assertThat(fruitData.get(0).get("color"), is("yellow"));
assertThat(fruitData.get(1).get("name"), is("apple"));
assertThat(fruitData.get(1).get("color"), is("red"));
assertThat(fruitData.get(2).get("name"), is("water melon"));
assertThat(fruitData.get(2).get("color"), is("green"));
}
}
다음과 같이 POJO 타입으로 매핑할 경우 더 직관적이고 명확하게 객체를 구성할 수 있다.
POJO (Plain Old Java Object)
Java EE와 같은 특정 프레임워크에 종속적이지 않은 자바 객체
@Data
public class Fruit {
private String name;
private String color;
}
@Data
@Component
@ConfigurationProperties("fruit")
public class FruitProperty {
private List<Fruit> list;
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class ConfigurationPropertiesTest {
@Autowired
FruitProperty fruitProperty;
@Test
public void test() {
List<Fruit> fruitData = fruitProperty.getList();
assertThat(fruitData.get(0).getName(), is("banana"));
assertThat(fruitData.get(0).getColor(), is("yellow"));
assertThat(fruitData.get(1).getName(), is("apple"));
assertThat(fruitData.get(1).getColor(), is("red"));
assertThat(fruitData.get(2).getName(), is("water melon"));
assertThat(fruitData.get(2).getColor(), is("green"));
}
}
[참고]