Web/MSA

[MSA] Spring Multi module 사용하기-1

정고정 2021. 7. 3. 15:51
반응형

 


InteliJ에서 SpringBoot Gradle Multi Module (자동으로) 추가하기

 

여기다 가장 쉽게 모듈 추가하는 법은 File > New Module 해서 같은 group에 넣는 방식임.

 

 

딱히 별 거 만질 필요도 없이 

최상위 디렉토리 아래에 이런 모듈이 생성된다. 그리고 gradle 아래 있는 .iml이 거슬리기 시작함.

iml은 IntelliJ IDEA Modul의 약어로, 개발하는 모듈의 의존성이나 경로, 기타 설정값 같은 정보를 담고 있다. 빌드 시에 얘를 참고하기 때문에 이 친구를 지워버리면 Gradle Sync Failed가 떠 버림. 

 

<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="demo" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4" />

 

까보면 이렇게 써 있다. 사실 별 게 없고, ide 설정파일에 가까워서 딱히 이 친구를 남기고 싶은 생각이 안 든다. 보통 개발 진행하시는 동안 이 파일 자체를 숨기시는 분들도 있고, git에 올릴 때도 이 친구는 .gitignore에 적어주는 친구임.

 

New Module로 만들어 버리면 .iml파일 뿐만이 아니라, 굳이 쓸 필요 없는 파일들이 자동으로 생성된다. 각 모듈마다 build.gradle만 있어도 기본은 돌아가는데 왜 굳이 iml이나 gradlew 까지 필수적으로 요구당해가면서 모듈을 써야 하징 이유가 있을지도 모르겠지만 아직 나는 공부중인 입장이라 잘 모르겠고, 나중에 필요하다면 만들어도 된다고 생각한다. 

 

그래서 자동으로 모듈을 생성하기보다는 수동으로 구조를 잡아 준 다음에, 각각 모듈들의 포함관계 등을 고려해서 프로젝트를 구성해 주기로 한다. 위에서 만든 demo 모듈은 그냥 지워준다. 

 


 

InteliJ에서 SpringBoot Gradle Multi Module (수동으로) 추가하기

 

 

참고 블로그

 

[MSA] MSA란 무엇인가? 개념 이해하기

MSA가 무엇인지 자세하게 알고싶어 개인적으로 정리하는 포스팅입니다. MSA? MicroService Architecture의 줄임말 👉🏻 마이크로서비스 아키텍처에 대한 정확한 정의는 없다. 하지만 마이크로서비스란

wooaoe.tistory.com

 

 

프로젝트 구조 만들기

 

먼저 새 프로젝트(최상위) 하나를 만들어 준다. 프로젝트 이름은 MSA고, Springboot는 2.4.8, java는 8이다. 패키지 구조는 다음과 같다.

 

이제 프로젝트 구조를 다음과 같이 변경해 준다. module-api, module-core, module-common. 이렇게 세 개의 모듈을 추가해 줄 예정이다. 

 

app디렉토리 생성 > api, common, core 디렉토리 생성 > src 디렉토리와 build.gradle 파일 복붙 

이렇게 build.gradle을 가진 전체 프로젝트(MSA)와, 각각 build.gradle과 src 트리구조를 가진 디렉토리(module-core, module-api, module-common)들을 수동으로 만들어 주었다. 

하지만 이 친구들은 그냥 폴더일 뿐이지 아직 모듈이라고 부를 수는 없다. New Module로 만들었다면 iml 파일 등이 연동 처리를 해 주었겠지만 여긴 없으니께

 

빨간 오류가 나는 건 당연하다. 지금까지는 한 건 파일구조를 만드는 일일 뿐이고, 이제부터 이 파일구조들을 모듈로 인식해 전체적으로 하나의 프로젝트로 작동할 수 있게끔 해야 한다.

 

처음 있던 src 구조를 그대로 복붙해왔으므로 module 안에는 당연히 MsaApplication.java 클래스들과 그 안의 main문이 중복으로 존재한다. 각각의 클래스 이름을 변경해 주자.

/*[module-api] MsaApplication -> ApiApplication*/

package com.study.msa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ApiApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApiApplication.class, args);
    }

}

module-core에 있는 클래스도 CoreApplication으로 바꿔준다. 그런데 module-common의 경우는 조금 다르다. 이 모듈은 공통으로 쓰는 친구들을 관리하는 모듈이므로 딱히 main문이 필요할 일이 없다. 그러므로 module-common은 메인문이 있는 클래스자체를 지워준다. 

 

 

build.gradle 설정 건드리기

메인부터 빌드해 들어갈 때, 자바의 경우에는 jar파일을 만든다. 메인이 없는 module-common의 경우 jar 파일이 필요 없으므로 build.gradle에 표시해 주자. 

/*[module-common] build.gradle*/
bootJar {
    enabled = false
}

jar {
    enabled = true
}

module별로 추가적인 dependency가 필요하다면 해당 모듈의 builld.gradle안에 dependency를 알아서 추가하면 된다.

 

이제 root 프로젝트의 build.gradle을 다음과 같이 변경해 준다. 

/*[root] build.gradle*/

buildscript {
    ext {
        springBootVersion = '2.4.8'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath "io.spring.gradle:dependency-management-plugin:1.0.11.RELEASE"
    }
}
allprojects {
    group = 'com.study'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = 1.8

    apply plugin: 'java'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
}

subprojects{
    repositories {
        mavenCentral()
    }

    dependencies {
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
    }
}

그리고 settings.gradle에 module들을 include해 준다.

rootProject.name까지는 기본적으로 적혀 있다.

/*settings.gradle*/
rootProject.name = 'msa'
include 'app:module-api', 'app:module-core', 'app:module-common'

 

아직은 모듈이라고 부르기 그렇지만 저 세가지를 모듈로 만들 거니까. 아직까지는 빌드하면 당연히 오류가 뜬다.

 

 

빌드!

여기까지 마치고 코끼리를 눌러서 root의 build.gradle을 빌드해 주면 잘 돌아간다.

  • 각 모듈의 build.gradle에는 dependency만 존재하면 된다.
  • Main문이 없는 common의 gradle에는 jar 설정도 필수로 넣어줘야 함.
  • Main문이 있는 api와 core의 경우에는 dependency에 web을 넣어줄 것.

BUILD SUCCESSFUL!

그런데 여기서 좀 이상한 게 뜬다. 

리포지토리가 왜 없음. root인 msa의 build.gradle에 repository를 명시해 줬는데 왜 이렇게 뜨지 이거 저번에 해결했었는데 까먹었으니까 일단은 로직 짜고 테스트부터 돌려보기로함

 

반응형