[๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ] Spring Boot Multi Module๋กœ MSA ํ™˜๊ฒฝ ๊ตฌ์„ฑํ•˜๊ธฐ

1. ๊ฐœ์š”

์˜ˆ์ „์— ๋ดค๋˜ Spring Cloud ๊ฐ•์˜๋ฅผ ๋ณต์Šตํ•˜๋ฉฐ ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆฌ๋ฐ, SAGA ํŒจํ„ด, CQRS ๋“ฑ MSA์— ์‚ฌ์šฉ๋˜๋Š” ์—ฌ๋Ÿฌ ๊ธฐ์ˆ ๋“ค์— ์ตํžˆ๊ธฐ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ํ•™์Šตํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. 

 

์ฒ˜์Œ multi module์„ ๊ณต๋ถ€ํ•ด์•ผ๊ฒ ๋‹ค ํ–ˆ๋˜ ๊ฑด kafka ๊ด€๋ จ ์„ค์ •๊ณผ ์ด๋ฒคํŠธ ํ†ต์‹ ์„ ์œ„ํ•œ dto๋“ค์˜ ์ฝ”๋“œ ์ค‘๋ณต ๋•Œ๋ฌธ์ด์—ˆ๋‹ค. MSA ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•˜๋ฉด์„œ๋„ ์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋œ๋‹ค๋Š”๊ฒŒ ๋งŽ์ด ๋Š๊ปด์กŒ๊ณ  ๊ณตํ†ต ๋ชจ๋“ˆ๋กœ ๋นผ๊ณ  ์‹ถ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค. 

๋˜ํ•œ JWT ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆ, ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ„ ๋กœ์ง๋„ ์–ด๋””๋กœ ๋นผ์•ผํ•  ์ง€ ๊ณ ๋ฏผ์ด ๋˜์—ˆ๋‹ค. 

 

 

์ •๋ง ์˜ˆ์ „์— multi module์— ๋Œ€ํ•ด์„œ ๊ฐ•์˜๋ฅผ ๋ณธ ์ ์ด ์žˆ๋Š”๋ฐ, ๊ทธ ๋• ์ด๋Ÿฐ๊ฒŒ ์žˆ๊ตฌ๋‚˜ ํ•˜๊ณ  ๋„˜์–ด๊ฐ”์ง€๋งŒ ์ด๋ฒˆ์—” ์ œ๋Œ€๋กœ ์•Œ์•„๋ณด๊ณ  multi module๋กœ msa ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•ด๋ณด๋ ค ํ•œ๋‹ค. 

 

 

 

 

 

 

 

 

2. ๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ

โœ… ๋ชจ๋“ˆ

Oracle Java ๋ฌธ์„œ์—์„œ ๋ชจ๋“ˆ์ด๋ž€ ํŒจํ‚ค์ง€์˜ ํ•œ ๋‹จ๊ณ„ ์œ„์˜ ์ง‘ํ•ฉ์ฒด์ด๋ฉฐ, ๊ด€๋ จ๋œ ํŒจํ‚ค์ง€์™€ ๋ฆฌ์†Œ์Šค๋“ค์˜ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ทธ๋ฃน์ด๋ผ๊ณ  ์ •์˜ํ•˜๊ณ  ์žˆ๋‹ค.
์ด๋•Œ ๊ฐ ๋ชจ๋“ˆ์€ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœ, ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

 

โœ… ๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ 

๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ์€ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋ชจ๋“ˆ๋“ค์„ ํ•˜๋‚˜์˜ ํ”„๋กœ์ ํŠธ ์•ˆ์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. 

๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ ์•ˆ์—์„œ ๊ฐ๊ฐ์˜ ๋ชจ๋“ˆ์€ ์„œ๋กœ๋ฅผ ํ–ฅํ•œ ์˜์กด์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.


์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ชจ๋“ˆ์„ ์ƒ์„ฑํ•  ๋•Œ ๋ฐ˜๋“œ์‹œ ๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด์•ผํ•˜์ง„ ์•Š์ง€๋งŒ ์ฝ”๋“œ ์ค‘๋ณต ์ œ๊ฑฐ, ๋ชจ๋“ˆ๊ฐ„ ์˜์กด์„ฑ์„ ์œ„ํ•ด ์ €์žฅ์†Œ์— ๋ฐฐํฌํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ์  ๋“ฑ ์žฅ์ ์ด ์žˆ๋‹ค. 

 

 

 

ํšŒ์› ์‹œ์Šคํ…œ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณด์ž. 

 

ํšŒ์› ์‹œ์Šคํ…œ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋…๋ฆฝ์ ์ธ ํ”„๋กœ์ ํŠธ ๋‹จ์œ„๊ฐ€ ์žˆ๋‹ค. 

  • member internal api : ๋‚ด๋ถ€์— ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€์—์„œ ํ˜ธ์ถœํ•˜๋Š” api ์„œ๋ฒ„
  • member external api : ๊ณ ๊ฐ ํ™”๋ฉด์—์„œ ํ˜ธ์ถœํ•˜๋Š” api ์„œ๋ฒ„
  • member batch : ์ฃผ๊ธฐ์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์„œ๋ฒ„

 

 

[ ๋‹จ์ผ ๋ชจ๋“ˆ๋กœ ๊ตฌ์„ฑ๋œ ๋ฉ€ํ‹ฐ ํ”„๋กœ์ ํŠธ ]

 

3๊ฐ€์ง€ ํ”„๋กœ์ ํŠธ ๋ชจ๋‘ ์œ ์ €๋ผ๋Š” ๋™์ผํ•œ ๋„๋ฉ”์ธ์— ๋Œ€ํ•ด์„œ ๊ตฌ์„ฑํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค. (ex. Member ๋„๋ฉ”์ธ ๋ชจ๋ธ)
 
๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ์— ์ด๋Ÿฌํ•œ ์ค‘๋ณต ์ฝ”๋“œ์— ์ˆ˜์ •์‚ฌํ•ญ์ด ์ƒ๊ธด๋‹ค๋ฉด ์„ธ ๋ชจ๋“ˆ์˜ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ ๋‚œ์ด๋„๊ฐ€ ์˜ฌ๋ผ๊ฐˆ ๊ฒƒ์ด๋‹ค. 

 

 

[ ๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ๋กœ ๊ตฌ์„ฑ๋œ ๋‹จ์ผ ํ”„๋กœ์ ํŠธ ] 

์œ„์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ ์ž ๋‹จ์ผ ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ชจ๋“ˆ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๊ฐ€ ๋‚˜์™”๋‹ค. 

 

์œ„ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ํ•˜๋‚˜์˜ ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ ๊ธฐ์กด์˜ ํ”„๋กœ์ ํŠธ ๋‹จ์œ„๋Š” ๋ชจ๋“ˆ์ด ๋˜์—ˆ๊ณ , ๊ณตํ†ต๋œ ์ฝ”๋“œ(common)๋Š” ๋ถ„๋ฆฌํ•ด์„œ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

 

 

 

 

 

 

3. ๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ & DDD & MSA

๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ์€ ์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ์œผ๋‹ˆ DDD, MSA์˜ ๊ฐ ๊ฐœ๋…๋“ค๋ถ€ํ„ฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ์งš๊ณ  ๋„˜์–ด๊ฐ€๋ฉด

 

MSA ๋ž€?

MSA๋Š” ์‹œ์Šคํ…œ์„ ๋…๋ฆฝ์ ์ธ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜์ด๋‹ค. ๊ฐ ์„œ๋น„์Šค๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœ, ๋ฐฐํฌ, ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๋ฉฐ ํŠน์ • ๋„๋ฉ”์ธ์— ์ดˆ์ ์„ ๋งž์ถ”์–ด ์„ค๊ณ„๋œ๋‹ค. MSA๋Š” ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์—์„œ ์„œ๋น„์Šค ๊ฐ„์˜ ์—ฐ๊ด€์„ฑ์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ๋…๋ฆฝ์ ์ธ ์„œ๋น„์Šค๋กœ ๊ตฌ์„ฑ๋˜๋„๋ก ํ•˜์—ฌ, ์‹œ์Šคํ…œ์˜ ์œ ์ง€๋ณด์ˆ˜์™€ ํ™•์žฅ์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ์œ ๋ฆฌํ•˜๋‹ค

 

 

DDD ๋ž€?

DDD๋Š” ๋„๋ฉ”์ธ ์ง€์‹์„ ๋ฐ˜์˜ํ•œ ๋ชจ๋ธ๋ง์„ ํ†ตํ•ด ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ด€๋ฆฌํ•˜๋Š” ์„ค๊ณ„ ๋ฐฉ์‹์ด๋‹ค. ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋„๋ฉ”์ธ์„ ์‹๋ณ„ํ•˜๊ณ  ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๋ชจ๋ธ์„ ์ค‘์‹ฌ์œผ๋กœ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•œ๋‹ค. DDD ์„ค๊ณ„๋ฅผ ํ†ตํ•ด ๊ฐ ๋งˆ์ดํฌ๋กœ ์„œ๋น„์Šค๋“ค์€ ์„œ๋น„์Šค ๊ฐ„ ์˜์กด์„ฑ์„ ๋‚ฎ์ถ”๊ณ  ๋…๋ฆฝ์ ์ธ ๋ฐฐํฌ์™€ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค. 

 

 

 

์œ„ ์„ธ ๊ฐ€์ง€๋Š” ์„œ๋กœ ๋ณด์™„์ ์ด๋ฉฐ ๊ฐ์ž์˜ ์žฅ์ ๋“ค์„ ํ•ฉ์ณ ์œ ์—ฐํ•˜๊ณ  ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

์˜ˆ๋ฅผ ๋“ค์–ด, DDD(๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„)๋กœ ์‹œ์Šคํ…œ์„ ๋„๋ฉ”์ธ ์ค‘์‹ฌ์œผ๋กœ ์„ค๊ณ„ํ•˜์—ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ํ•œ ํ›„, MSA ์•„ํ‚คํ…์ฒ˜๋กœ ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ ๋„๋ฉ”์ธ์„ ๋…๋ฆฝ์ ์ธ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋กœ ๋ถ„๋ฆฌํ•จ์œผ๋กœ์จ ์‹œ์Šคํ…œ์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ๋…๋ฆฝ์ ์œผ๋กœ ๋ฐฐํฌ ๋ฐ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. 

 

 

๋˜ํ•œ, MSA๋Š” ๋…๋ฆฝ์ ์ธ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์šด์˜ํ•˜๋Š” ๋ฐฉ์‹์ด๋ฏ€๋กœ, ๊ณตํ†ต์œผ๋กœ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ(์˜ˆ: ์ธ์ฆ, ๋กœ๊น…, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋“ฑ)์ด ์—ฌ๋Ÿฌ ์„œ๋น„์Šค์—์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ๊ตฌํ˜„๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์Šคํ”„๋ง ๋ฉ€ํ‹ฐ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๊ณตํ†ต ๊ธฐ๋Šฅ์„ common ๋ชจ๋“ˆ๋กœ ์ถ”์ถœํ•˜์—ฌ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

MSA์™€ ๋ฉ€ํ‹ฐ๋ชจ๋“ˆ์˜ ๊ฒฐํ•ฉ์€ ๊ฐ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๊ฐ€ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋งŒ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์—ฌ ์•„ํ‚คํ…์ฒ˜์˜ ์œ ์—ฐ์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ ์ž‘์„ฑ์„ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

 

4. Spring Boot ์—์„œ ๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ ์ ์šฉํ•˜๊ธฐ 

๋“ค์–ด๊ฐ€๊ธฐ ์•ž์„œ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ€์ ธ๊ฐ”๋‹ค. 

 

Spring Cloud ๊ด€๋ จ ๋ชจ๋“ˆ์ธ api gateway, eureka ๊ฐ€ ์žˆ๊ณ , ์˜ˆ์ „์— ๋งŒ๋“ค์–ด๋’€๋˜ todo ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— member ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค. temp-server๋Š” ๊ทธ๋ƒฅ micro server ๊ฐœ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค.. ใ…‹ใ…‹

common์€ ๊ณตํ†ต ๋ชจ๋“ˆ ์—ญํ• ์„ ํ•˜๊ณ  infra๋Š” kafka, zipkin ๋“ฑ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋„์šฐ๋Š” ๋ฐ ํ•„์š”ํ•œ docker ๊ด€๋ จ ์„ค์ •์„ ํ•ด๋‘์—ˆ๋‹ค. 

๐Ÿ“ฆspring-cloud-test
 โ”ฃ ๐Ÿ“‚apigateway
 โ”ฃ ๐Ÿ“‚common
 โ”ฃ ๐Ÿ“‚eureka
 โ”ฃ ๐Ÿ“‚gradle
 โ”ฃ ๐Ÿ“‚infra
 โ”ฃ ๐Ÿ“‚member-server
 โ”ฃ ๐Ÿ“‚temp-server
 โ”ฃ ๐Ÿ“‚todo-app-server
 โ”ฃ ๐Ÿ“œ.gitattributes
 โ”ฃ ๐Ÿ“œ.gitignore
 โ”ฃ ๐Ÿ“œbuild.gradle
 โ”ฃ ๐Ÿ“œgradlew
 โ”ฃ ๐Ÿ“œgradlew.bat
 โ”ฃ ๐Ÿ“œHELP.md
 โ”— ๐Ÿ“œsettings.gradle



 

๋ฃจํŠธ ๋ชจ๋“ˆ ์ƒ์„ฑ

๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ์„ ์ „๋ถ€ ๊ด€๋ฆฌํ•  ๋ฃจํŠธ ๋ชจ๋“ˆ์„ ์ƒ์„ฑํ•œ ํ›„ src ๋””๋ ‰ํ† ๋ฆฌ๋Š” ์‚ญ์ œํ•ด์ค€๋‹ค. 

 

src ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ๋‚จ์•„์žˆ์„ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์€ ์—๋Ÿฌ์™€ ๋งˆ์ฃผ์น˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

Execution failed for task ':bootRun'.
> Failed to calculate the value of task ':bootRun' property 'mainClass'.
   > Main class name has not been configured and it could not be resolved

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
BUILD FAILED in 1s
3 actionable tasks: 2 executed, 1 up-to-date

 

 

 

 

ํ•˜์œ„ ๋ชจ๋“ˆ ์ƒ์„ฑ

ํ•˜์œ„ ๋ชจ๋“ˆ ์—ญํ• ์„ ํ•  ์ƒˆ๋กœ์šด ๋ชจ๋“ˆ ์ƒ์„ฑ์€ ์ธํ…”๋ฆฌ์ œ์ด์—์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์ „์ฒด ๋ชจ๋“ˆ์—์„œ ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉํ•  ๋””ํŽœ๋˜์‹œ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ฃจํŠธ ๋ชจ๋“ˆ์—์„œ ์ฃผ์ž…ํ•ด์ฃผ๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณธ์ธ์˜ ๋ชจ๋“ˆ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์˜์กด์„ฑ๋งŒ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. 

 

 

์ƒ์„ฑ ํ›„ ์•„๋ž˜ ํŒŒ์ผ๋“ค์€ ์ „๋ถ€ ์ง€์›Œ์ฃผ์ž.

 

์‚ฝ์งˆ์„ ์ข€ ํ–ˆ๋˜ ๋ถ€๋ถ„์ธ๋ฐ, gradle ๊ด€๋ จ ํŒŒ์ผ์ด ํ•˜์œ„ ๋ชจ๋“ˆ์— ๋‚จ์•„์žˆ์œผ๋ฉด gradle build๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ ํ•˜์œ„ ๋ชจ๋“ˆ๋„ ๋”ฐ๋กœ ๋งํฌ๋ฅผ ๋งบ๊ฒŒ ๋˜๊ณ  ๋ฃจํŠธ ๋ชจ๋“ˆ์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์—†๋‹ค. 

 

 

 

์ฒ˜์Œ ๋ชจ๋“ˆ์„ ์ƒ์„ฑํ•˜๊ณ  ๋‚œ ํ›„์˜ build.gradle์˜ ๋ชจ์Šต์ด๋‹ค. 

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.5'
    id 'io.spring.dependency-management' version '1.1.6'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
    useJUnitPlatform()
}

 

 

์—ฌ๊ธฐ์„œ dependencies๋งŒ ๋‚จ๊ฒจ๋‘๊ณ  ์ „๋ถ€ ์ง€์›Œ์ฃผ์ž. (๋ฃจํŠธ ๋ชจ๋“ˆ๋กœ๋ถ€ํ„ฐ ์ฃผ์ž… ๋ฐ›์„ ๋‚ด์šฉ์€ ์ œ์™ธํ•˜๊ธฐ ์œ„ํ•จ, ์žˆ์–ด๋„ ๋ฌธ์ œ ์—†์ง€๋งŒ ์ฝ”๋“œ ์ค‘๋ณต)

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

 

 

 

 

๋ฃจํŠธ ๋ชจ๋“ˆ์—์„œ build.gradle ์„ค์ •

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.5'
    id 'io.spring.dependency-management' version '1.1.6'
}

bootJar.enabled = false // ๋ฃจํŠธ ํ”„๋กœ์ ํŠธ์˜ bootJar ๋น„ํ™œ์„ฑํ™”

subprojects {
    group = 'com.example'
    version = '0.0.1-SNAPSHOT'

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

    java {
        toolchain {
            languageVersion = JavaLanguageVersion.of(21)
        }
    }

    bootJar.enabled = true
    jar.enabled = false

    tasks.named('test') {
        useJUnitPlatform()
    }

    ext {
        set('springCloudVersion', "2023.0.3")
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

        // ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•  ์˜์กด์„ฑ ์ถ”๊ฐ€
    }

    dependencyManagement {
        imports {
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }
}

 

 

ํ•˜์œ„ ๋ชจ๋“ˆ์— ์ฃผ์ž…ํ•  ๋‚ด์šฉ๋“ค์€ subprojects {} ์•ˆ์— ๋„ฃ์–ด์ค€๋‹ค. 

์‹คํ–‰ ๋ชฉ์ ์„ ๊ฐ€์ง„ ํ•˜์œ„ ๋ชจ๋“ˆ์€ bootJar๋งŒ ํ™œ์„ฑํ™” ํ•˜๊ณ  Jar๋Š” ๋น„ํ™œ์„ฑํ™” ํ•ด์ค€๋‹ค.

 

ํ•˜์ง€๋งŒ common ๋ชจ๋“ˆ ๊ฐ™์ด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ๊ณต์œ ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด BooJar๋ฅผ ๋น„ํ™œ์„ฑํ™” ํ•˜๊ณ  Jar๋Š” ํ™œ์„ฑํ™” ํ•ด์ค€๋‹ค. 

 

 

project(':common') {

    bootJar { enabled = false } // ๊ณตํ†ต ๋ชจ๋“ˆ์€ bootJar ๋กœ ํŒจํ‚ค์ง• ํ•  ํ•„์š” ์—†์Œ
    jar { enabled = true }

    dependencies {
    }
}

 

์ด๋ ‡๊ฒŒ ๋ฃจํŠธ ๋ชจ๋“ˆ์—์„œ ํ•˜์œ„ ๋ชจ๋“ˆ์„ ํŠน์ •ํ•ด์„œ gradle ์„ค์ •์„ ํ•ด์ค„ ์ˆ˜๋„ ์žˆ๊ณ , common ๋ชจ๋“ˆ์˜ build.gradle ํŒŒ์ผ์—์„œ ์ง์ ‘ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

 

 

๋ฃจํŠธ ๋ชจ๋“ˆ์˜ setting.gradle ์„ค์ •

rootProject.name = [๋ฃจํŠธ ๋ชจ๋“ˆ]
include [ํ•˜์œ„ ๋ชจ๋“ˆ1]
include [ํ•˜์œ„ ๋ชจ๋“ˆ2]
include [ํ•˜์œ„ ๋ชจ๋“ˆ3]
include [ํ•˜์œ„ ๋ชจ๋“ˆ4]
include [ํ•˜์œ„ ๋ชจ๋“ˆ5]
...

 

๋ฃจํŠธ ๋ชจ๋“ˆ์—์„œ ์„ค์ •ํ•œ build.gradle ํŒŒ์ผ์„ ์ฃผ์ž…ํ•  ๋ชจ๋“ˆ ๋“ค์„ include ํ•ด์ฃผ๋ฉด spring boot์—์„œ multi module ์„ค์ •์ด ๋์ด๋‚œ๋‹ค.

 

์ดํ›„ gradle refresh๋ฅผ ๋Œ๋ ค๋ณด๋ฉด ์•„๋ž˜ ์ฒ˜๋Ÿผ ๋ฃจํŠธ ๋ชจ๋“ˆ ํ•˜๋‚˜๋งŒ ๋œจ๊ณ  ๊ทธ ์•„๋ž˜์— ํ•˜์œ„ ๋ชจ๋“ˆ์ด ๋– ์•ผํ•œ๋‹ค. 

์ƒ์œ„์— ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ๋œฌ๋‹ค๋ฉด ์„ค์ •์ด ์ž˜๋ชป๋œ ๊ฒฝ์šฐ์ด๋‹ค. 

 

 

 

 

์ด๋ ‡๊ฒŒ ๊ตฌ์„ฑ์ด ๋๋‹ค๋ฉด ๋ชจ๋“ˆ๋“ค์„ ์ด๋ ‡๊ฒŒ ๋ชจ์•„์„œ ๋ณผ ์ˆ˜ ์žˆ๊ณ  ๋ณต์ˆ˜ ์„ ํƒ ํ›„ ํ•œ๋ฒˆ์— ์‹คํ–‰๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋„ˆ๋ฌด ํŽธํ•œ ๊ฒƒ... ๐Ÿ˜€