All Projects → ihoneymon → multi-module

ihoneymon / multi-module

Licence: other
다중 모듈을 가지는 스프링 부트 기반 그레이들 프로젝트 구성하기

Programming Languages

java
68154 projects - #9 most used programming language
HTML
75241 projects

스프링 부트 기반 멀티모듈 프로젝트 구성 가이드

애플리케이션을 만들 때 다중 모듈을 가지는 프로젝트를 구성하고 각 모듈의 조합에 따라서 다른 기능을 가지는 애플리케이션(예: 관리자 애플리케이션, 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가 적용된다.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].