멀티모듈이라는 단어가 나온지는 꽤 됐으나 최근에 멀티모듈이라는 것에 대해 들었다.
대략적으로 이해한 부분은 아래와 같다.
- 하나의 프로젝트가 방대해질수록 프로젝트가 가지는 의존성이 어마어마해진다.
- 프로젝트의 의존성들을 각 모듈에 따라 분리시킴으로써 모듈들이 자신의 역할을 수행하게하고 필요한 의존성들을 가지고 있게 한다.
- 새로운 구조가 생길 때마다 필요한 모듈을 미리 구현한 각각의 모듈을 사용함으로써 굳이 선언해서 사용하지 않음으로써 의존성을 분리시키고 관리를 좀 더 수월하게 하기 위함이다.
멀티 모듈로 프로젝트를 만들어가다보니 부딪히는 부분이 많았다.
첫 번째는 타 모듈에서 서버를 실행할 경우 Entity 를 가지고 있는 모듈의 의존성을 받아써도 JPA 관련 DDL 로그가 나타나지 않았다.
현재 만들고 있는 멀티 모듈의 초기 프로젝트 구조로 다음과 같다.
- java-api : Web 과 관련된 REST API 를 제공하고 비즈니스 로직들을 담당하게 한다.
- java-core : 데이터 접근 계층과 그에 관련된 역할을 담당한다.
java-api 모듈의 경우 비즈니스 계층으로 해두고 java-web 이라는 모듈을 따로 생성해서 프레젠테이션 계층으로 설정할까 고민중이지만, 우선은 처음하는 거기도 하고 같이 쓰게 했다.
그리고 각 모듈의 build.gradle 설정은 다음과 같이 했다.
// java-core
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
// java-api
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
// root
project(":java-api") {
dependencies {
implementation project(":java-core")
}
}
다음으로 java-core 에서 패키지를 만들어서 Entity 와 JpaRepository 를 추가했다.
@Entity
@Table(name = "board", indexes = {@Index(columnList = "title", name = "idx_title")})
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title", length = 50)
private String title;
}
public interface BoardRepository extends JpaRepository<Board, Long> {
}
여기서 java-core 의 application.properties 파일에 다음을 추가했다.
당연히 core 모듈에서 JPA 와 h2 의존성을 쓰고 있으니 해당 모듈에 추가하는 게 맞다고 생각했다.
spring.datasource.hikari.jdbc-url=jdbc:h2:mem://localhost/~/testdb;
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
이후 java-api 모듈에서 서버를 실행했다.
기본적으로 JPA 를 사용하면 자동으로 테이블 정의어 로그가 나타나야 하는데 안나타났다.
생각해보니 java-api 모듈에는 Entity 관련 코드들이 없으며, api 모듈에 있는 Component 를 스캔하기 때문에 java-core 모듈에 작성된 Entity 들이 등록이 되지 않은 것이다.
그래서 검색을 해보았는데, @EntityScan 을 사용해서 다른 모듈을 읽어서 Entity 들을 스캔할 수 있었다.
따라서 코드를 추가.
@EntityScan("com.multi.core")
@SpringBootApplication
public class MultiModuleJavaApiApplication {
public static void main(String[] args) {
SpringApplication.run(MultiModuleJavaApiApplication.class, args);
}
}
물론 여기서도 안됐다. 여전히 DDL 은 나오지 않았다.
여기서 application.properties 의 설정 코드를 직접 java-api 모듈에 옮겨서 동작을 시켰다.
드디어 해결을 했다.
어떻게 보면 당연한 결과이다. 이유는 다음과 같다.
- 서버를 실행하는 java-api 모듈은 환경설정이 비워져 있었다.
- JPA 나 H2 관련 설정이 아무것도 없고 java-core 에 환경설정을 했으니 java-api 모듈을 실행해도 변화가 없었던 것이다.
여기서 추가적으로 생각해볼 부분이 있다.
JPA 와 H2 설정은 java-core 모듈이 의존하는 덕분에 사용할 수 있는 부분이다. java-api 가 java-core 의 모듈에 의존한다면 application.properties 에 작성한 환경설정 코드는 java-core 모듈에 선언하는 게 맞다고 생각했다.
그렇다고 생각했기 때문에, 만약 다른 모듈의 환경설정을 적용시킬 수 있다면 java-core 에 작성해서 쓰는게 맞는 것 같다라는 내 주관적인 결론을 내렸음.
검색을 해보니 금방 나왔는데, 기존에 단일 프로젝트에서 쓸 떄 쓰던 방법을 쓰면 됐다.
- @PropertySource 를 통한 방식 ( java-core 모듈 환경설정 이름을 변경했음 )
@EntityScan("com.multi.core")
@SpringBootApplication
@PropertySource({"classpath:application-core.properties"})
2. properties 파일에 spring.config.import 선언하는 방식 ( 둘 중 하나를 사용 )
spring.config.import=application-core.properties
spring.config.import=classpath:application-core.properties
한편으로는 java-api 는 java-core 모듈에 의존하고 있기 떄문에 사실은 java-api 의 환경설정에 설정코드를 추가해서 사용해도 이미 의존하고 있는 부분이므로 상관없을 것 같다는 의견도 들었다.
서로 멀티 모듈에 대해서 잘 모르기 때문에 실무에서 얘기를 해볼 경우에는 각자 생각이 분명이 다를것 같기 떄문에 프로젝트 구조나 상황에 따라서 적용하는 위치가 달라질 것으로 예상한다.
'Back-End > Spring' 카테고리의 다른 글
멀티 모듈에서 JPA 모듈을 사용하기 위한 설정 및 내 견해 (2) | 2022.06.23 |
---|---|
로깅 라이브러리(@Slf4j) 사용시 log 메서드의 올바른 사용법 (0) | 2021.12.18 |
Spring Boot Logback 설정으로 로그파일 생성 (0) | 2021.09.04 |
Spring Boot + Gradle + MyBatis 설정 (0) | 2021.07.05 |
Spring Boot Test Code 동작순서 정렬 - @TestMethodOrder (0) | 2021.06.25 |