개발일기장

근황 + 멀티 모듈 이야기

자몽포도 2023. 9. 2. 23:30

오랜만에 블로그를 쓰니 근황을 좀 이야기해보려고 한다. 퇴근 후에 공부를 한다는건 생각보다 힘들었다.

 

집에 칼같이 와도 7시 30분 정도?

집에 와서 씻고 밥먹고 조금 쉬면 10시가 훌쩍 넘는다.

그러다가 좀 더 쉬면 자는거고... zz

 

아니면 가볍게 2시간 정도 공부를 한다. 생각보다 집중력이 좋지 않았다.

그 기간동안에는 Linux, SQL 이나 회사에서 사용하는 기술 스택으로 아주 자그마한 프로젝트를 만들어보았다.

하루도 빠짐없이 공부한건 맞지만.. 많이는 못해서 나에게 미안하네 ㅎㅎ 

주말에는 그동안에 만나지 못했던 친구들을 만났다. 앞으로 몇 주 정도는 친구를 더 만날 것 같긴 하다..ㅎ

 

 

 

이제 본격적으로 멀티 모듈 이야기로 들어가보겠다. 우선 단일 모듈에서 멀티 모듈로 전환하는건 이번이 2번째이다. 

 

 

첫번째 멀티 모듈 전환 xuni-cafe-server


 

프로젝트를 간단하게 소개하자면 스터디 카페 예약 서비스이다. 당시에는 개발에 절여져서 개발 스터디 프로젝트와 연관성이 높아서 만들어두면 좋지 않을까 생각했다.

 

 

GitHub - JxxHxxx/xuni-cafe-server: MongoDB, Webflux로 개발하는 xuni-cafe-api 서버

MongoDB, Webflux로 개발하는 xuni-cafe-api 서버. Contribute to JxxHxxx/xuni-cafe-server development by creating an account on GitHub.

github.com

 

이 프로젝트의 주요 기술 스택은 webflux/MongoDB다. 좋은 경험이었지만 당분간은 더 이상 건들지 않을 것 같다. 사실 이 기술들을 적어도 지금 재직중인 회사에서는 사용하지 않을 것 같지만 새로운 기술을 학습한다는 것 자체가 프로그래밍을 조금 더 다양한 관점으로 바라볼 수 있게 만들어준다.

 

이 프로젝트를 멀티 모듈로 전환하는건 생각보다 어려운 일은 아니었기에 모듈을 나누는 방법과 나눴을 때 이점 정도를 생각해보았다. 

 

 

 

두번째 멀티 모듈 전환 xuni-study


이 프로젝트는 그룹 스터디를 만들고 스터디 진행 상황을 체크하는 서비스가 있는 프로젝트다. 기술 스택도 많은 서비스 회사에서 채택중이기 때문에 학습용으로도 좋다. 그리고 여담이지만 배포자동화 서버는 AWS 프리 티어 기간이 곧 끝나서 내렸다. 추석 연휴 때 쯤 github-action으로 다시 배포 자동화 기능을 구축하려고 한다.

 

 

 

GitHub - JxxHxxx/xuni-study-group-server: 예비 개발자를 위한 스터디 중개 서비스

예비 개발자를 위한 스터디 중개 서비스. Contribute to JxxHxxx/xuni-study-group-server development by creating an account on GitHub.

github.com

 

 

 

모듈 나눌 때 세운 기준


우선 저는 이 프로젝트를 시작할 때 DDD를 적용했습니다. 네... 저는 DDD 책 한권을 보고 매료된 응애개발자입니다...

여튼 DDD를 적용했기 때문에 도메인 단위로 모듈을 나눠도 비용이 크지는 않았을 것 같습니다. 하지만 많은 서버를 사용할 수는 없었기에 좋은 선택지는 아니라고 봤어요.  group, product, review, statistics 등... 도메인 단위로 서버에 올릴려면 너무 많이 필요하니까...ㅎ

 

 

그래서 core, batch, admin, api 구조를 선택했습니다다. 여기서 조금 나뉘었던게 infrastructure 의 위치였어요.

결론적으로는 infrastructure 는 api, batch, admin 에 다 들어갑니다.

 

처음에는 core 모듈에 두기로 했습니다. 그런데 굳이 좋은 선택지는 아니라고 느꼈어요.

만약 core에 repository를 두면 batch, admin, api 에 필요한 모든 메서드가 다 들어가게 되서 너무 복잡해질 것 같다는 생각이 들었습니다. 특히 admin에서 사용하는 기능들은 api 모듈에서 호출할 수 있는 여지를 주고 싶지 않았어요.

 

 

 

 

모듈을 나누면서 발생했던 트러블


 

 

1. 빈 스캔 범위

 

 

일반적으로 단일 모둘로 부트로 프로젝트를 실행하면 @SpringBootApplication 에 속성값을 지정하지 않더라도 애플리케이션이 잘 실행됐습니다. 하지만 모듈을 나눈 이후부터 스프링 의존 관계가 제대로 주입되지 않아 애플리케이션을 실행할 수 없었습니다. 

 

 

아래와 같이 빈을 찾지 못해 의존 관계를 주입하지 못합니다.

 

먼저 @SpringBootApplication 애노테이션에는 @ComponentScan 이 포함되어 있습니다. 그리고 이 애노테이션의 역할은 

bean 들을 스캔하는 것입니다. 그리고 스캔 범위 때문에 위 같은 문제가 생겼습니다.

 

@ComponentScan 을 지정하지 않으면 해당 애노테이션이 선언된 클래스 내 패키지와 그 하위 패키지의 빈들을 스캔합니다. 이로 인해 외부 모듈에 존재하는 Bean들은 스캔 범위에 해당하지 않기 때문에 문제가 생기는 것입니다.

 

 

아래와 같이 적절하게 빈을 스캔할 수 있도록 scanBasePackageClasses 속성을 설정합시다.

@SpringBootApplication(scanBasePackageClasses = {XuniCore.class, XuniApiApplication.class})

 

 

다른 방법으로는 scanBasePackages 를 설정해도 됩니다.

@SpringBootApplication(scanBasePackages = {"com.xuni.api", "com.xuni.core"})

 

이렇게 설정하면 해당 클래스 혹은 패키지 경로 내 존재하는 클래스와 하위 패키지에 존재하는 클래스의 빈들을 읽습니다.

 

 

이것저것 해보다가 알게 된 것


반면 빌드를 통해 jar 파일을 말면 jar 파일 내 의존 관계 주입을 위한 빈 class 파일들이 모두 있기 때문에 basePackage를 설정하지 않아도 문제가 없습니다. 빌드를 해서 만들어진 jar 압축 파일을 까보면 외부 모듈의 jar 파일들이 들어오게 됩니다.

 

 

 

실제로 있는걸 볼 수 있죠. 이걸 통해서 의존 관계를 주입하지 않을까 해요. 더 깊은 내용은 제가 알지 못해서 더 설득력있는 설명은 못할 것 같네요.

 

 

 

 

 

 

엔티티를 읽지 못하는 문제


아직 이건 더 좋은 해결책을 찾아야하는데 우선은 이렇게 해결했습니다. 외부 모듈에 존재하는 엔티티를 못 읽는 것 같습니다. 그래서 XxxRepository Bean 들을 만들지 못하는 지경에 이릅니다.

 

@EntityScan을 통해 엔티티를 읽을 경로를 지정할 수 있습니다.

@EntityScan(basePackageClasses = XuniCore.class)

 

 

다만 이로 인해 테스트 레이어에서 문제가 생겼습니다. 저는 컨트롤러 단에서 단위 테스트를 수행할 때 @WebMvcTest 를 사용하고 있었습니다. 이 애노테이션은 Web 에 필요한 빈들만 읽어요. @Controller, @ControllerAdvice 이런 애들만요. 다른 애들은 @MockBean 등을 사용해서 모킹하는데요. @EntityScan 을 선언했더니 테스트 레이어에서 EntityManager를 빈으로 주입하려 합니다. 이후 repository 관련 빈들을 주입하지 못하는 오류가 발생합니다.

 

그래서  repository 관련 빈도 등록할 수 있도록 @SpringBootTest / @AutoConfigureMockMvc 를 설정해서 문제를 일단 해결해두었습니다. 그런데 @EntityScan 선언으로 인한 문제인지는 너무나도 추측뿐이기 때문에 조금 더 확실한 원인이나 해결 방법이 있으면 글을 다시 써보려고 합니다.

 

 

그럼 20000