-
Notifications
You must be signed in to change notification settings - Fork 35
build multi module guide
애플리케이션을 만들 때 다중 모듈을 가지는 프로젝트를 구성하고 각 모듈의 조합에 따라서 다른 기능을 가지는 애플리케이션(예: 관리자 애플리케이션, API 제공 애플리케이션과 웹페이지를 제공하는 웹 애플리케이션) 배포본을 구성한다.
나는 각 애플리케이션의 기본실행환경은 다음과 같이 구분짓는다:
-
로컬(
local
): 개발자 실행환경 -
개발(
dev
):develop
브랜치를 기준으로 깃저장소 밀어넣기(push)가 발생날 때 빌드배포 발생 -
스테이지(
stage
): 개발된 기능을 기획자와 확인하기 위한 목적으로 준운영환경에 가깝게 운영 -
운영(
prod
): 실제 사용자에게 기능제공
Note
|
프로파일 명칭은 팀이나 기업마다 조금씩 다르겠지만 대략 저런 구조를 가진다고 생각한다. |
기존에는 이렇게 구성을 했었고 이와 관련된 설정은 모두 애플리케이션 속성파일(application.yml
혹은 application.properties
)에 스프링 프로파일을 이용하여 구분지었다. 스프링 부트는 애플리케이션 속성 파일에서 사용할 스프링 프로파일을 명시하여 활성화된 프로파일에 따라 다르게 적재하는 기능을 제공한다. 각 모듈별로 이 기능을 활용하여 프로파일로 속성값을 정의해놓고 최종적으로 애플리케이션 실행단계에 적용하는 것이 가능하다.
multi-module: 루트 프로젝트
└─ core-module: Entity, Repository 및 Utility 등
└─ batch-module: 배치(batch) 모음
└─ api-module: API 애플리케이션
└─ admin-module: 관리자 애플리케이션
└─ (todo) web-module: 웹 애플리케이션
위와 같은 구성을 가지는 모듈을 기준으로 설명을 하고자 한다. 애플리케이션 실행환경은 위에서 언급했듯이 '로컬', '개발', '스테이지’와 '운영’으로 구성된다.
각 모듈 하위에는 다음과 같이 애플리케이션 속성파일을 지정한다.
.
├── admin-module
│ └── src
│ └── main
│ ├── java
│ │ └── io.honeymon.springboot.multimodule
│ │ └── admin
│ │ ├── AdminModuleApplication.java
│ │ └── view
│ │ └── IndexController.java
│ └── resources
│ ├── application.yml
│ └── logback-spring.xml
├── api-module
│ └── src
│ └── main
│ ├── java
│ │ └── io.honeymon.springboot.multimodule
│ │ └── api
│ │ ├── ApiApplication.java
│ │ └── root
│ │ └── RootController.java
│ └── resources
│ ├── application.yml
│ └── logback-spring.xml
├── batch-module
│ └── src
│ └── main
│ ├── java
│ │ └── io.honeymon.springboot.multimodule
│ │ └── batch
│ │ ├── BatchModuleApplication.java
│ │ └── batchjob
│ │ └── SimpleBatchJob.java
│ └── resources
│ ├── application.yml
│ └── logback-spring.xml
└── core-module
└── src
└── main
├── java
│ └── io.honeymon.springboot.multimodule
│ └── core
│ ├── entity
│ │ ├── BaseAdmin.java
│ │ └── BaseUser.java
│ ├── package-info.java
│ └── repository
│ ├── BaseAdminRepository.java
│ └── BaseUserRepository.java
└── resources
└── application-core.yml
이 파일에서 살펴봐야할 공통적인 속성파일은 application-core.yml
파일이다. 파일은 각각 애플리케이션 데이터소스(DataSource) 구성과 외부연계API에 사용할 클라이언트 구성에 필요한 인증키 정보를 가지고 있다.
application-core.yml
spring:
flyway:
enabled: false
---
spring.profiles: local
spring:
datasource:
url: jdbc:h2:mem:multi
username: SA
password:
---
spring.profiles: dev
spring:
datasource:
url: jdbc:h2:mem:multi-dev
username: dbdev
password: dbdevpassword
---
spring.profiles: stage
spring:
datasource:
url: jdbc:h2:mem:multi-stage
username: dbstage
password: dbstagepassword
---
spring.profiles: prod
spring:
datasource:
url: jdbc:h2:mem:multi-prod
username: dbprod
password: dbprodpassword
---
spring.profiles: db-prod
spring:
datasource:
url: jdbc:h2:mem:multi-db-prod
username: dbprod
password: dbprodpassword
Note
|
별도의 프로파일로 중복되는 속성을 정의하기 보다는 실행하는 환경에 따라서 환경변수로 외부 속성변경방식을 사용하길 바란다. |
위 파일을 살펴보면 공통적으로 spring.profiles
를 정의하였다. spring.profiles.active
에서 {"local", "dev", "stage", "prod"}
중에서 활성화된 프로파일을 따라 적재된다.
application-core.yml
파일을 이용하는 api-module/application.yml
을 살펴보자:
api-module/application.yml
# commons
spring:
profiles:
include:
- core
client:
id: honeymon
key: 20180416
---
spring.profiles: local
client:
id: honeymon-local
key: 20180416-local
---
spring,profiles: dev
client:
id: honeymon-dev
key: 20180416-dev
---
spring.profiles: stage
client:
id: honeymon-stage
key: 20180416-stage
---
spring.profiles: prod
client:
id: honeymon-prod
key: 20180416-prod
api-module/application.yml
의 구성은 생각보다 간결해진다. spring.profiles.include
를 통해서 application-core.yml
파일을 프로파일로 읽어온다. spring.profiles.include
을 이용해서 다른 모듈이나 프로파일로 정의된 애플리케이션 속성파일을 지정할 수 있다.
api-module/application.yml
에는 로깅레빌을 선언하는 정도의 선언이 기재되어 있을뿐, 데이터베이스 정보와 클라이언트 정보를 기술하고 있지는 않다.
Note
|
애플리케이션 속성은 애플리케이션 구동 시점에 적재되어 키밸류(Key-Value)의 Map 으로 합쳐지게 된다. 이 과정에서 중요한 것은 활성화하는 프로파일의 순서다. |
활성화화는 프로파일의 순서에 따라서 속성값이 달라진다. 즉, 나중에 활성화되는 프로파일의 값이 최종적으로 반영이 된다. 그 예로 다음과 같이 프로파일 순서를 {"prod", "db-prod"}
와 {"db-prod", "prod"}
로 선언했을 때 값이 변경되는 것을 볼 수 있다.
@ActiveProfiles({"prod", "db-prod"})
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProdAndDbProdTest {
@Autowired
private Environment env;
@Test
public void testGetDataSourceUrl() {
assertThat(env.getProperty("spring.datasource.url")).isEqualTo("jdbc:h2:mem:multi-db-prod");
}
}
@ActiveProfiles({"db-prod","prod"})
@RunWith(SpringRunner.class)
@SpringBootTest
public class DbProdAndProdTest {
@Autowired
private Environment env;
@Test
public void testGetDataSourceUrl() {
assertThat(env.getProperty("spring.datasource.url")).isEqualTo("jdbc:h2:mem:multi-prod");
}
}
-
애플리케이션은 기능에 따라 애플리케이션 속성파일에 프로파일을 정의한다.
-
예: DB 관련:
application-db.yml
-
예: 외부API 호출시 인증:
application-auth.yml
-
-
기능정의 애플리케이션 속성파일을 애플리케이션 속성파일에서 포함시켜 선언한다.
spring: profiles: include: - db - auth
-
사전 정의한 배포환경별 프로파일
{"local", "dev", "stage", "prod"}
외에 별도로 선언이 필요하다면 각 기능별 애플리케이션 속성파일을 추가한다.application-dbprod.yml
변경spring: datasource: url: jdbc:h2:mem:multi-db-prod username: dbprod password: dbprodpassword flyway: enabled: false
추가한 속성파일을 spring.profiles.active=prod,dbprod
처럼 활성화할 프로파일 마지막에 선언하여 속성을 한번에 변경하는 방법도 유효한 사용방법이다.
-
주의 ::
spring.profiles.active
에서 여러 프로파일을 선언할 때 순서에 주의하자.-
동일한 속성(키)을 정의한 프로파일이 있다면 마지막에 선언된 프로파일 속성값이 적용된다.
-
-
spring.profiles.active=prod
를 선언했을 때-
application-db.yml
:spring.profile: prod
속성 적용 -
application-auth.yml
:spring.profiles: prod
속성 적용 -
application.yml
:spring.profiles: prod
속성 적용 -
application.yml
포함선언(spring.profiels.include
)한 각 속성파일(ex:application-db.yml
,application-auth.yml
) 내부에 정의한spring.profiles: prod
가 적용된다.
-
-
이름 : 김지헌
-
별명 : 허니몬(honeymon)
-
사이트: http://honeymon.io
-
블로그 : http://honeymon.io / http://ihoney.pe.kr / http://java.ihoney.pe.kr
-
트위터 : @ihoneymon
-
이메일 : [email protected]