본문 바로가기

STUDY/Spring

Spring Boot | 멀티 모듈 프로젝트 (Multi Module)

OAuth2를 하다가.. 리소스 서버와 인증 서버를 따로 두기 위해... 고민하던 중

멀티 모듈이라는 것이 있다길래 해봤습니다.. 

 

참고!

 

Gradle 멀티 프로젝트 관리

안녕하세요! 이번 시간에는 아시는 분들은 거의다 아시는(!?) Gradle을 이용한 멀티 프로젝트(모듈) 관리에 대해 소개하려고 합니다. 모든 코드는 Github에 있으니 참고하셔서 보시면 더 좋으실 것

jojoldu.tistory.com


1. 프로젝트 생성

스프링 이니셜라이저 혹은 다양한 방법으로 스프링 부트 프로젝트를 생성하면 된다.

나는 스프링 이니셜라이저를 이용했음!

그리고 1번에서 생성한 프로젝트가 루트 프로젝트가 된다.

SpringBoot 2.4.2
Gradle
IntelliJ (커뮤니티 버전)
Java11

2. 모듈 생성

세 개의 모듈을 만들 것임

📌ResourceServer

📌AuthorizationServer

📌DBServer: 위의 두 모듈이 공유할 코드들을 작성할 모듈! => 이는 나중에 각 모듈이 jar로 가져감

 

프로젝트 우클릭 -> New -> Module
Gradle ->Java -> Next
모듈명 입력 후 Finish

3. 루트 프로젝트의 settings.gradle확인

모듈을 만들면 settings.gradle에 자동적으로 아래와 같이 작성되어져 있을 것

만약 없다면..? 저렇게 쓰세요ㅠ;;

4. 루트 프로젝트의 build.gradle작성

이 부분이 참 어려웠는데... 부트 버전과 그래이들 버전에 맞게 잘 작성해주면 됩니다...

subprojects부분이 중요.. 모듈에서 공통적으로 사용하는 라이브러리들을 넣어주면.. 끗

buildscript {
	ext {
		springBootVersion = '2.4.2'
	}
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
	}
}

repositories {
	mavenCentral()
}

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

	group = 'rest'
	version = '0.0.1-SNAPSHOT'
	sourceCompatibility = '11'

	repositories {
		mavenCentral()
	}

	dependencies {
		implementation 'org.springframework.boot:spring-boot-starter-web'
		// ..모듈들이 공통적으로 사용
	}

}

 

5. DBServer build.gradle작성

다른 모듈에는 이미 루트 build.gradle에서 사용할 라이브러리들을 작성해두었고,

DBServer에만 DB와 MyBatis를 사용하기 위한 설정을 한다.

그리고 이 모듈의 코드들을 다른 모듈들이 사용할 수 있다!

 

중요한게 jar와 bootJar부분... 저렇게 설정을 해줘야 다른 모듈에서 jar로 불러올 수 있음!

dependencies {
    // MyBatis
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4'
    // MySQL
    runtimeOnly 'mysql:mysql-connector-java'
}

jar {
    enabled = true
}
bootJar {
    enabled = false
}

 

+ application.yml에서 DB정보 입력하고... Config클래스도 작성해주면 됨...

 

6. 루트 build.gradle 수정

최하단에 아래와 같이 입력해준다.

이렇게 해주면... 비로소... DBServer의 코드들을 다른 모듈들에서 불러다 쓸 수 있게 된다!

project(':AuthorizationServer') {
	dependencies {
		compile project(':DBServer')
	}
}

project(':ResourceServer') {
	dependencies {
		compile project(':DBServer')
	}
}

 

7. 모듈별 application.yml작성 및 부트어플리케이션 설정

DBServer말고 다른 모듈들은 스프링부트 프로젝트(?)라고 생각하면 된다.

스프링 부트로 시작할 수 있도록 작성해주기!

@SpringBootApplication
public class AuthorizationApplication {

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

}

그리고 application.yml (혹은 application.properties)에서 port번호를 각각 다르게 설정해준다. (DBServer는 하지 않음)

이 두 모듈은 나중에 각각 Jar로 빌드된다.

server:
  port: 8081
spring:
  devtools:
    livereload:
      enabled: true
  datasource:
    hikari:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: 
      username: 
      password: 

 

8. 테 스 트

DBServer에서 User값을 가져오는 코드들을 작성한다...

그리고 AuthorizationServer에서 Service를 작성 

@Service
public class UserService {

    @Autowired
    UserMapper userMapper;

    public User findAllUsers() {
        return userMapper.findAllUsers();
    }
}

 

컨트롤러에서 받아와보자...

@RestController
public class WebController {

    @Autowired
    UserService userService;

    @GetMapping("/hello")
    public String hello() {
        return userService.findAllUsers().toString();
    }

}

 


그래들 버전 업데이트에 따라 약간의 작성 방식을 변경했다

루트 build.gradle에서 buildScript로 작성하던 걸 안 해도 된다. plugins로 작성하면 끝.

plugins {
	id 'org.springframework.boot' version '2.5.5'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

subprojects {

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

	group = 'com.demo'
	version = '0.0.1-SNAPSHOT'
	sourceCompatibility = '11'

	configurations {
		compileOnly {
			extendsFrom annotationProcessor
		}
	}

	repositories {
		mavenCentral()
	}

	dependencies {
    
    }

}

 

모듈 별 설정하는 부분도 살짝 변경한다. compile은 이제 쓰지 않는다.

implementation으로 변경해줬다.

project(':api') {
	dependencies {
		implementation project(':common')
		// 해당 프로젝트에서만 필요한 의존성은 여기에 추가할 수 있다.
	}
}