{"componentChunkName":"component---src-templates-post-template-jsx","path":"/works/posts/2022-07-23--001","result":{"data":{"site":{"siteMetadata":{"title":"Blog by Eunyoung","subtitle":"작업 기록 블로그","copyright":"© All rights reserved.","author":{"name":"EunYoung","twitter":"#"},"disqusShortname":"","url":"https://ssongey.github.io"}},"markdownRemark":{"id":"ac854c5a-54b4-5bcc-820c-57cda9812d28","html":"<br/>\n<p>이번에 본사 인프라에서 kep 인프라로 이전하게 되면서 Ruby on Rails 로 되어있는 프로젝트를 Kopring 으로 변경하기로 결정을 하였다.<br>\n해당 프로젝트는 여러개의 서비스가 한 프로젝트에 모두 담겨 있는데, 멀티 모듈로 구성하면 좋을 듯 하여 코프링으로 멀티모듈을 구성하게 되었다.</p>\n<h2>✔️ 환경</h2>\n<ul>\n<li>SpringBoot <code class=\"language-text\">2.7.2</code></li>\n<li>Kotlin <code class=\"language-text\">1.6.21</code></li>\n<li>Gradle <code class=\"language-text\">7.5</code></li>\n</ul>\n<br/>\n<h2>✔️ 구성 방법</h2>\n<p>현재 한 프로젝트 내에 여러 도메인의 서비스들이 존재한다.<br>\n추후 서비스 단위로 외주를 주거나, 다른 팀으로 넘어갈때를 대비하여 아래와 같은 구조로 생각했다.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/f793b/001-01.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 38.75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABRElEQVQoz4VRO66CUBCl14SKzobWBVjYkNgQCmELFDRasAXCDtyAoXYLNAixMlrYaGmlMRijIf6iwHmZSS4xD1/eJJP7mTPnnjlXKssSFPf7Hdfrlfd5nqMoCl6pfjgcsN1u8X6/+f4zCXM+n7mPsNIn4ePxwO9Yr9cIggDj8RhhGOJbXC6X74RCIb38er1477ouJEniVBSFa2IK6qXzn4S32632+mQygeM4GAwG8DyPm0XPvwqJkM6kNE3TyhtSK3BUOx6POJ1Olac1QgEmn3RdR7/fh23bWK1WMAwDpmlC0zTM53PGjUYj9Ho9WJaF4XBYJxS++L6PRqMBVVXR6XSQJAlkWUa73eY1iqLK12aziVarhW63iyzLIIRVIz+fT/5RIplOp1gsFtjv95jNZnxHudvteOTNZsOYOI6xXC55fKHwB0cQKaJDgXi+AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 01\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/d9199/001-01.png\"\n        srcset=\"/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/8ff5a/001-01.png 240w,\n/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/e85cb/001-01.png 480w,\n/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/d9199/001-01.png 960w,\n/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/f793b/001-01.png 1404w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<br/>\n<h2>✔️ 멀티 프로젝트 생성</h2>\n<h3>1. 프로젝트 생성</h3>\n<p>1.1. 프로젝트 생성은 spring initializer / kotlin + gradle 로 구성하였다.\n\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/75a80/001-02.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 51.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABn0lEQVQoz41S207CQBT0g4zRoNx6b7d3sKhYCgU1Ud989AN89NOgrRVEX/wWyHh2wYiJEJtMN+d0dzoze/ZAz3K55Ave5+/opX0koyvEgxRxP0U3SdEb3lB/iIs4wUUvQZdwmQzQ7pxjOpthk2OPvxaLhSgmeY66rEHSDFSbMhTdRFMzobshDNuFajKqddQkhfapOKicYDzJsMmxIlyz50UBxTDheAFk3RAEmmWjFUUIow5sP4TlegLM81FXVGR5sZ1wPP1ELX6ClD7jIHwkQpt+YMF0PDhBa6VQ1QVkUl+pNTDJ8h0KyykUFhAJW1lljiB0icxrtaFaTNQ8kp2E34GW5StsN4BPhzVSo67ByWw/EEp1Zos4/qWwKEtopIrnxg8YtgPT9eFH5wiiM/inHTBSK9G33QoXK8IXCphZDnS6UW5L4xZ57bUpCg+yRWA+ZLLNrR/Xm3QpfylcF+Msw+FxVYwF3yxR+A1FExarTYl6DdHn4GO1f1ShsZlsz/BtPkdvMMTN3b0YZI4kHdE6EusPqH91i7PrB8zmH78G+wudtgztEFtoJQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 02\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/d9199/001-02.png\"\n        srcset=\"/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/8ff5a/001-02.png 240w,\n/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/e85cb/001-02.png 480w,\n/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/d9199/001-02.png 960w,\n/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/75a80/001-02.png 1134w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<p>1.2. 상위 프로젝트의 src 디렉토리는 불필요하므로 삭제한다.\n\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/84bf8/001-03.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 50.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABfElEQVQoz52STWsTURSG85uExjgfmWQyH/mYz8zkJpNAzEJBpBt/geC6qypddFm6FJSCP0VEsPgDMslCXEzQzuPNNC0I2hovvBw4l/Pcl/eeGrtTlmVVv30veHn2kaO3n3jz/guvK11y/O66nlxc8ur8M6cfvvLj59Vvs9tauwFe7ZrLfIUWPKEfzIinh3Qnh+iDx7cy/AUHlrybv6DYbP4OLMvr1/I8x3VNwshHiATH7aBqDZpNtZJhaChKnTSNKIrifoe5dNi2u9heRDKeEgxTWpaLapgoUmqrw4GiE6XjfYAOdi8kSgRBnNDzAjpOF6XZQmuZ1BVNAsUeQMvBHYSk44x4JDB3sP8DrlaYlo3uxfgiI4hinN6ApmlVMNVo7+/Q6vaw/SGhzCkcJjLHhL4f3kIfqnrl/N+AyyUdOdweSXdBKNcnxNu67HsyW5dHusGDegM/Ht4NvGmu12uy+YJoMkNMpqRbySxH2RSRzUjEpPqop8+es/nDHv4C2t1SYeAHCiYAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 03\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/d9199/001-03.png\"\n        srcset=\"/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/8ff5a/001-03.png 240w,\n/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/e85cb/001-03.png 480w,\n/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/d9199/001-03.png 960w,\n/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/84bf8/001-03.png 1162w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<h3>2. 서브 모듈 생성</h3>\n<p>2.1. core, api-server1, api-server2 모듈을 생성한다.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/41d3c/001-04.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 490px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 64.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACv0lEQVQ4y22STW8bZRDHfYBvwA0oakIbaESbGsfeV++u19619927a69f4iROoSmtIkBc2krwGbhx4cgHoBWIIg4tt9Iv9WO8aaJW6uGnZ56Z0f+ZmWcat9yIpjOiqVk0LY99x+em5rDTMvhs32C30635vG3WfKFa9X0T29wv4hf+xvu7LrdnZ2xPHrAXrdjP73Ddm7MbrthLjtGmp+z4C7b7Fa3xCbfEd9Wdcjtd08xOaBdf8WE3571dhw86EY09vYsaT+hUJ7hxiSO2PhzjjWf00ymDrMLL5/TSqvaZQY7mp/SSCW4yFc7zm7ZP2+7RSEcmYRiSRAlhMiYQojRnFGcMo4x4XHL33n1Ov3lAVlZ1PM4Kyc3Fzs/zs5IojkiGBg3VNDFsFz0qMPwI1wuwvRH9YcQgiMUOMHs+Rs/DdH26wsV5SX+ILhqaaDU6Rhe98yVbx2fczCYU8YjJtCROQooiZX00xxvYaGoLw2hj6O9G1dp0ZHwNxbC4XvxC97s/aJ0+xfvhb+xv/8L9/hnK/T+5unjC9vLpJVvLJ2+xvfidrdUzdsY/o+jGpkKLT8vfsB79w41HzwkevyL68T+Sn14xePiSaycv+OjgOVcOX/DxanP+yydHbyD+K+uXovGrCOoyQxFsqTrF6oy8uscwlbYXa8LxnDCfMT9cM1kcMlutmS6P6vmplszL7qNZrxFbMR0UGZ8IdtlXFSbVMdPyjvxaKL8sazHwavwgxBsFOP0Brj+UD3TQuha6Zb+FapjngkotqJNLFVExIc1LEqGl6DJkk7ZmStxANW2pwhIxRwSc+l7HhY1v0+mloKKoeNKmtvyaSHZyFKekRSnVZozLaf3IRuQCVYT7w4CymjNbHmC5A5nfGxW2pcKkOsDbLGiSSoVFLRSI7QWysOOiFtK69qWg64/qhzZ5Vk9m+Lrl/wF98OW9QDoQwAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 04\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/41d3c/001-04.png\"\n        srcset=\"/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/8ff5a/001-04.png 240w,\n/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/e85cb/001-04.png 480w,\n/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/41d3c/001-04.png 490w\"\n        sizes=\"(max-width: 490px) 100vw, 490px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/6568d/001-05.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 48.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACC0lEQVQoz31SWWsTURTOv1GxbdLS1MyS2TNblmmMtM2YdFJEUPBdSvHZpUkrLn2Q2ie1gpBfk/8RiDOJWT/PvSGCuFz4uHfOzDnzLTelFhxoBRc67QyKE0CxS8ibNmTTgaxbUM0C0ts7aJ+dg63xeIzpdPoH5vM5UoIkIicJkDWNmk1IdgDR8iEaDiTTg6BZEBUNtzYyeHHaxnIt8K+V0ssNSG6dGPnQiIntl1AMduFVduET3FIFbrGMrCChc/6aN32PE8TJCMmQ4QdHnAwxnkyIYe0YmfJTiIUaVF2HYlh8qGG7kIgZY8dqa5ktvH1/gcFggP0wRCtqohFFOAjraEaH8IpFXH+9RsowVGiaTOxM5Emy5fpwiBH307R4TdYMbGbv4PjkGbrdLoolD7VqANdzoWoKDFNHZjONq6uPSDHT83qBs2Dmm45HcCkoGwbtrM6Grm9t42W7g16vR6H58PbuI6jW6KcF5PIqbqyl8eGSBuaNpekqsdEsGxbJZb6x82oYw22S/ObdBfr9Pu7uhzh6/AR7ByH5XUVQu8e//fyFJDM5DIwdKzKp7Lyqr95tEMPTzhkPJY5jjEYjDHkoQ9qHSJIEExYK82ZHlJGTFc5UUnUIJIGlmqV6VpD58831DJ6/Wl6bxeI/16b14CGldYR64/A3hM3oFxpRC5XGI1x++sabZrMZH/o3/ATVMOQt5nliUQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 05\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/d9199/001-05.png\"\n        srcset=\"/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/8ff5a/001-05.png 240w,\n/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/e85cb/001-05.png 480w,\n/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/d9199/001-05.png 960w,\n/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/07a9c/001-05.png 1440w,\n/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/6568d/001-05.png 1660w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<p>2.2. src를 제외하고는 불필요 하므로 삭제한다.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/6db8e21f1029bcca6557df9e1597079a/d99f2/001-07.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 336px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABYlAAAWJQFJUiTwAAACBElEQVQ4y41UaW/TQBDNvwJix0d8xcfWcQ6nlMRxU9IjTYtCk54gJKJ+AAkhJNQv/NjHzMJWPVwpHzazx+zzmzdvUzNsBw2rCScIIbIuLNOCZtqwHE/u6zTn+G9tw2y68FoRNMOSZ09HjQ/9MEa708fNrz/ITq9xsVrh6uYz8u0dHJ+c4mx5jqPjORZnS7kuJ3vyI1WgNd6s0zAME2aaozE8gEgShIlAvWHCJeZBlMB2fYqxXCvmlYD8wxebfgstYut5Pi7X35CPdtHp5ej2B7JMzlFDXa4EVEmqBIO0KqYziG5OgH2SoifZvarrMu+NbuC11rgHewpa42SbQIIkRbF3AJ+Y2q6HKNmS0WHmcYJYpDKyFBkxZ9aVDPkC6yK22lh8v4NYrXF5zk35hF6+fd+U/cMjLD4uMZufyLnjBY/Kf1ayTk2puy3o7QFCYsI24dJUAx5e3qgp7MOIyvEprn/eYbw/w3BU4F0xlmUrQAZRo1JDtoxKVmJHaYe6HpKByTLkUda5ik0lQ9bPJQZJ1sOHqy/U3QHSrIP+4K00Np9xZ18CeAbIWlnEgD1YXt8iXN2iHA0xJeEn76cQ7Uwy3xhQ+18yv1ONxDaCGFm+A5M+wvvqTW8C9rgpVFoYC/nwv/74jfJwjnG5i6KcyL0qi7zI8GH3eG4SKzYuG54Z8j/Spgz/AqR1JmK9CDruAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 07\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/6db8e21f1029bcca6557df9e1597079a/d99f2/001-07.png\"\n        srcset=\"/devHistoryBlog/static/6db8e21f1029bcca6557df9e1597079a/8ff5a/001-07.png 240w,\n/devHistoryBlog/static/6db8e21f1029bcca6557df9e1597079a/d99f2/001-07.png 336w\"\n        sizes=\"(max-width: 336px) 100vw, 336px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<br/>\n<h3>3. root 프로젝트 settings.gradle.kts 파일 설정</h3>\n<p><strong>settings.gradle.kts</strong> 는 빌드 대상 프로젝트를 설정하는 파일이다.<br>\n서브 모듈을 include 해주면 gradle 탭의 root 프로젝트 하위에 모듈이 표시가 된다.  </p>\n<p>3.1. settings.gradle.kts 파일 수정\n\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/31713c8de741e87fe65480052908597d/35890/001-08.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 35.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABGElEQVQoz52R206EMBRF51t8cmgLBVpgGArlfhuDmInx/39ke6hG39T4sHJ6ktPV3fZUtwP6YcY4LI6BsF2Dum+RmQtUppHkCVSqESmFMI6QFgXacUbZdGiGCWXbw04rmmnGSekE17xEZSxMbmCuFUkUdBZDX2LEWUSyCFESkkxChoL6FNP6hJk46iGuSdgdwjDW8IMAXHAwzsA5JxgYY989+6ziWHsIwgjjdsdw22C6CampkZU1FIVxQi4EvPMZnscI7wfoEJp7FBJ+/4x0uUPaBaKaHQ9J/SEUwncbXKpfOOYCulG33LC/vmHbX2DpDXNToai+hOLvQkroS4l2WrBuu/ucK4nyg/KfwkCGKGxLNCSxDiel+g4J3eORhS+pgwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 08\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/31713c8de741e87fe65480052908597d/d9199/001-08.png\"\n        srcset=\"/devHistoryBlog/static/31713c8de741e87fe65480052908597d/8ff5a/001-08.png 240w,\n/devHistoryBlog/static/31713c8de741e87fe65480052908597d/e85cb/001-08.png 480w,\n/devHistoryBlog/static/31713c8de741e87fe65480052908597d/d9199/001-08.png 960w,\n/devHistoryBlog/static/31713c8de741e87fe65480052908597d/07a9c/001-08.png 1440w,\n/devHistoryBlog/static/31713c8de741e87fe65480052908597d/35890/001-08.png 1582w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<p>3.2. 같은 root 프로젝트와 같은 레벨에 생긴 모듈들은 모두 unlink를 해준다.\n\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/9cea8/001-09.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 47.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAACFklEQVQoz42RS08TURiG+2MwhiDQltqWXu30wgzTDi0FWtoOLagkbpRbA7ZcpCjFBVUxuFIQjWGDkSZu2LjxL7WQsHk8c1ATd57kybs4b5583zm2o8+n7LUO2N0/YHuv9Q+Nl6+obTc5O//O/x5bpvSIHqeCI2QIxhgIJBkU3AlncMWnuO1VqTZasvzlrE11s8nyRpPF+gsW6s8lyxu7zC/UufjxUwiXTxnMH5J6fEJ6volabhApNlDMHRIzOwyk6iy1LqSwtrVDn8ON3e3HE4riDkRwBxW8cZ2egSE+HH/CZlZmCdyLYKTTxBIxNF1DG71BT+p4hr2s1epcXl5S39hEUUfJ5vKkxjJoKYNRgZGdZMg7zMcTISzOVPCFFSYKprhMEx3RUBIaMVUXqWJ3eVhcqdJut3myuIQ/rpLOF1D1pOwGI1FCSow+u5MjS5grFHF6fRjTJXQjTVzTicQS+MMRWbS73KxvPbtZWUwYjMbICuGkwMhkxXYK4WicfscQx5YwXzS56wuQFeLxyRwTuWlZCPwWOu56/gqra09xenyM6IaczBsI4RLDWHmrt4/3R8fYLIk17kjSkILhYFiWLDz+IL39g6zW1qVw//UbMqJfvv+AfMkkVyzJtJ5NF2/69ds5tpXVNcancsw+nMeszFEwy5TKFYoCc3ZO3OV5e/hOCq+uruh0OpJut0tXfNSf7Ii8vr7mF/qbo//mK1b7AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 09\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/d9199/001-09.png\"\n        srcset=\"/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/8ff5a/001-09.png 240w,\n/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/e85cb/001-09.png 480w,\n/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/d9199/001-09.png 960w,\n/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/9cea8/001-09.png 1278w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p><strong>⚠️  만약 unlink 를 안하면??</strong></p>\n<p>빌드를 시도할 경우 root 프로젝트의 <strong>하위 모듈이 빌드가 되지 않고</strong>, 같은 레벨에 있는 모듈이 빌드가 된다.<br>\n이는 파일명 자체에서도 확인할 수 있는데, 하위 모듈이 될 경우 해당 프로젝트 명은 콜론(:) 표시가 되어야 하는데, unlink를 하지 않은 api-server2의 경우 파일명 뒤에 프로젝트명에 콜론표시가 없다.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/67a79/001-11.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 38.75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABMUlEQVQoz52RyW7CMBCGeZeqhziQjZgsQJw4TsBZSBNBN5VL3/8d/toOordK5fBpxiP704xnIQ4NqoNEWR8haomirMDlCcPnN/r3K7rXK9rLl4llN2GXF5Bth5yXyFSuYQUHU+eccywojZBsUsQ0QRptTQxoiDCJFRH8dQgvmHE9H86GIuQNvL0A5RIBO8DLarhlZ+oLzw9g20Rh3+NS5+Q3Xy5nVrru+AjECdtmwpq3sFKB54jjOeZ4okwL1yD6MbENxEBA7BvkhpJZlgXHdSG7HuPbB17GEcemMUiFGfkuNB3+jb63clxkvEI1TJD9gEq2SFmBeMeQZvn/hY4SMlGjG88YzxfV7UktimOrpI8JXd2hQHlUo6ptD+OEfhiQFeUjwvkPdTfJnhlSTTaPq+s/qD8Gmt/sMKAAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 11\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/d9199/001-11.png\"\n        srcset=\"/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/8ff5a/001-11.png 240w,\n/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/e85cb/001-11.png 480w,\n/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/d9199/001-11.png 960w,\n/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/67a79/001-11.png 1408w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<h3>4. build.gradle.kts</h3>\n<p>많이 삽질한 단계…</p>\n<p>각각 모듈 내의 build.gradle.kts 에 설정을 해줘도 되지만, 관리를 편하게 하기 위해 <strong>root 프로젝트의 build.gradle.kts 파일에 모두 설정</strong>하도록 하였다. (그래서 위 서브 모듈 생성시에 src를 제외하고 모두 지웠다.)</p>\n<h4>AS IS)</h4>\n<div class=\"gatsby-highlight\" data-language=\"groovy\"><pre class=\"language-groovy\"><code class=\"language-groovy\"><span class=\"token keyword\">import</span> org<span class=\"token punctuation\">.</span>jetbrains<span class=\"token punctuation\">.</span>kotlin<span class=\"token punctuation\">.</span>gradle<span class=\"token punctuation\">.</span>tasks<span class=\"token punctuation\">.</span>KotlinCompile\n\nplugins <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">id</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.springframework.boot\"</span><span class=\"token punctuation\">)</span> version <span class=\"token string gstring\">\"2.7.2\"</span>\n\t<span class=\"token function\">id</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"io.spring.dependency-management\"</span><span class=\"token punctuation\">)</span> version <span class=\"token string gstring\">\"1.0.12.RELEASE\"</span>\n\t<span class=\"token function\">kotlin</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"jvm\"</span><span class=\"token punctuation\">)</span> version <span class=\"token string gstring\">\"1.6.21\"</span>\n\t<span class=\"token function\">kotlin</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"plugin.spring\"</span><span class=\"token punctuation\">)</span> version <span class=\"token string gstring\">\"1.6.21\"</span>\n<span class=\"token punctuation\">}</span>\n\ngroup <span class=\"token operator\">=</span> <span class=\"token string gstring\">\"com.example\"</span>\nversion <span class=\"token operator\">=</span> <span class=\"token string gstring\">\"0.0.1-SNAPSHOT\"</span>\njava<span class=\"token punctuation\">.</span>sourceCompatibility <span class=\"token operator\">=</span> JavaVersion<span class=\"token punctuation\">.</span>VERSION_17\n\nrepositories <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">mavenCentral</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\ndependencies <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.springframework.boot:spring-boot-starter-web\"</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"com.fasterxml.jackson.module:jackson-module-kotlin\"</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.jetbrains.kotlin:kotlin-reflect\"</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.jetbrains.kotlin:kotlin-stdlib-jdk8\"</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token function\">testImplementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.springframework.boot:spring-boot-starter-test\"</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\ntasks<span class=\"token punctuation\">.</span>withType<span class=\"token operator\">&lt;</span>KotlinCompile<span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n\tkotlinOptions <span class=\"token punctuation\">{</span>\n\t\tfreeCompilerArgs <span class=\"token operator\">=</span> <span class=\"token function\">listOf</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"-Xjsr305=strict\"</span><span class=\"token punctuation\">)</span>\n\t\tjvmTarget <span class=\"token operator\">=</span> <span class=\"token string gstring\">\"17\"</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\ntasks<span class=\"token punctuation\">.</span>withType<span class=\"token operator\">&lt;</span>Test<span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">useJUnitPlatform</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h4>TO BO)</h4>\n<div class=\"gatsby-highlight\" data-language=\"groovy\"><pre class=\"language-groovy\"><code class=\"language-groovy\"><span class=\"token keyword\">import</span> org<span class=\"token punctuation\">.</span>jetbrains<span class=\"token punctuation\">.</span>kotlin<span class=\"token punctuation\">.</span>gradle<span class=\"token punctuation\">.</span>tasks<span class=\"token punctuation\">.</span>KotlinCompile\n\nplugins <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">id</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.springframework.boot\"</span><span class=\"token punctuation\">)</span> version <span class=\"token string gstring\">\"2.7.2\"</span>\n\t<span class=\"token function\">id</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"io.spring.dependency-management\"</span><span class=\"token punctuation\">)</span> version <span class=\"token string gstring\">\"1.0.12.RELEASE\"</span>\n\t<span class=\"token function\">kotlin</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"jvm\"</span><span class=\"token punctuation\">)</span> version <span class=\"token string gstring\">\"1.6.21\"</span>\n\t<span class=\"token function\">kotlin</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"plugin.spring\"</span><span class=\"token punctuation\">)</span> version <span class=\"token string gstring\">\"1.6.21\"</span>\n<span class=\"token punctuation\">}</span>\n\nallprojects <span class=\"token punctuation\">{</span>\n\trepositories <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token function\">mavenCentral</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\nsubprojects <span class=\"token punctuation\">{</span>\n\tapply <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token function\">plugin</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.springframework.boot\"</span><span class=\"token punctuation\">)</span>\n\t\t<span class=\"token function\">plugin</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"io.spring.dependency-management\"</span><span class=\"token punctuation\">)</span>\n\t\t<span class=\"token function\">plugin</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"kotlin\"</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span>\n\n\tgroup <span class=\"token operator\">=</span> <span class=\"token string gstring\">\"com.example\"</span>\n\tversion <span class=\"token operator\">=</span> <span class=\"token string gstring\">\"0.0.1-SNAPSHOT\"</span>\n\tjava<span class=\"token punctuation\">.</span>sourceCompatibility <span class=\"token operator\">=</span> JavaVersion<span class=\"token punctuation\">.</span>VERSION_17\n\n\tdependencies <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.springframework.boot:spring-boot-starter-web\"</span><span class=\"token punctuation\">)</span>\n\t\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"com.fasterxml.jackson.module:jackson-module-kotlin\"</span><span class=\"token punctuation\">)</span>\n\t\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.jetbrains.kotlin:kotlin-reflect\"</span><span class=\"token punctuation\">)</span>\n\t\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.jetbrains.kotlin:kotlin-stdlib-jdk8\"</span><span class=\"token punctuation\">)</span>\n\n\t\t<span class=\"token function\">testImplementation</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"org.springframework.boot:spring-boot-starter-test\"</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span>\n\n\ttasks<span class=\"token punctuation\">.</span>withType<span class=\"token operator\">&lt;</span>KotlinCompile<span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n\t\tkotlinOptions <span class=\"token punctuation\">{</span>\n\t\t\tfreeCompilerArgs <span class=\"token operator\">=</span> <span class=\"token function\">listOf</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\"-Xjsr305=strict\"</span><span class=\"token punctuation\">)</span>\n\t\t\tjvmTarget <span class=\"token operator\">=</span> <span class=\"token string gstring\">\"17\"</span>\n\t\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token punctuation\">}</span>\n\n\ttasks<span class=\"token punctuation\">.</span>withType<span class=\"token operator\">&lt;</span>Test<span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token function\">useJUnitPlatform</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">project</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\":core\"</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">project</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\":api-server1\"</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\tdependencies <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token function\">project</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\":core\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">project</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\":api-server2\"</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\tdependencies <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token function\">implementation</span><span class=\"token punctuation\">(</span><span class=\"token function\">project</span><span class=\"token punctuation\">(</span><span class=\"token string gstring\">\":core\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><strong>allprojects</strong></p>\n<ul>\n<li>root project 및 하위 프로젝트 모두에 대한 의존성 관리</li>\n</ul>\n<p><strong>subprojects</strong></p>\n<ul>\n<li>setting.gradle 에 include 된 프로젝트를 전부 관리</li>\n</ul>\n<p><strong>project</strong></p>\n<ul>\n<li>하위 프로젝트의 의존성 관리</li>\n<li>core 의 경우 공통 모듈이기 때문에 api-server1, api-server2 에 의존성 주입</li>\n</ul>\n<br/>\n<h3>5. application.yaml 설정</h3>\n<p>각 api 모듈들은 각 다른 포트로 실행되어야 하므로 port 를 다르게 지정해준다.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/bb2fd/001-12.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA90lEQVQY03WP227CMBBE8zvEjuNr4lzIhUIkWlUoCFJKSFX6//8wtS0hlYc+HO2svbNjR8M44rT84HS943j9xuT1fA+8jhOG/QFN/xJ4Px9xuS2YPmecHZfbFz7mJfB2GFE1HaK638G2AzZ9h23fwtYdVNFAO1ReQUqNNOUQmUK5blG3G2ybArvGwtoCJrfIHNoYMJYisjYDdwbFGdaKQEkBU3VuSQpGiRtiTrPQC6mQCgnBKEqxclpBlS0IoYjjFSiliHRmIZRB4owxIe7yf7Q2kEqDCxECOOdP+LPIZDm4+1aSJC4lDkZfHzx6X/2LfDih9GnmL78bdKVMosvjEgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 12\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/d9199/001-12.png\"\n        srcset=\"/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/8ff5a/001-12.png 240w,\n/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/e85cb/001-12.png 480w,\n/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/d9199/001-12.png 960w,\n/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/bb2fd/001-12.png 1058w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<br/>\n<br/>\n<h2>✔️ 공통모듈 의존성 테스트</h2>\n<p>core 모듈에 요청 로깅 필터 클래스 생성 후 빈으로 등록하여 각 api 모듈에서 로깅이 되는지 확인 한다.</p>\n<br/>\n<h3>1. core 모듈에 RequestLoggingFilter 생성 후 Bean으로 등록</h3>\n<p>ReqeustLoggingFilter 클래스</p>\n<div class=\"gatsby-highlight\" data-language=\"kotlin\"><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">class</span> RequestLoggingFilter <span class=\"token operator\">:</span> <span class=\"token function\">OncePerRequestFilter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> accessLogger<span class=\"token operator\">:</span> Logger <span class=\"token operator\">=</span> LoggerFactory<span class=\"token punctuation\">.</span><span class=\"token function\">getLogger</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"ACCESS_LOGGER\"</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">doFilterInternal</span><span class=\"token punctuation\">(</span>originalRequest<span class=\"token operator\">:</span> HttpServletRequest<span class=\"token punctuation\">,</span> originalResponse<span class=\"token operator\">:</span> HttpServletResponse<span class=\"token punctuation\">,</span> filterChain<span class=\"token operator\">:</span> FilterChain<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        filterChain<span class=\"token punctuation\">.</span><span class=\"token function\">doFilter</span><span class=\"token punctuation\">(</span>originalRequest<span class=\"token punctuation\">,</span> originalResponse<span class=\"token punctuation\">)</span>\n        accessLogger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"access log\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>WebConfig 클래스에서 bean 으로 등록</p>\n<div class=\"gatsby-highlight\" data-language=\"kotlin\"><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Configuration</span>\n<span class=\"token keyword\">class</span> WebConfig <span class=\"token operator\">:</span> WebMvcConfigurer <span class=\"token punctuation\">{</span>\n\n    <span class=\"token annotation builtin\">@Bean</span>\n    <span class=\"token keyword\">fun</span> <span class=\"token function\">requestLoggingFilter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> FilterRegistrationBean<span class=\"token operator\">&lt;</span>RequestLoggingFilter<span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">val</span> filterRegistrationBeanRequest<span class=\"token operator\">:</span> FilterRegistrationBean<span class=\"token operator\">&lt;</span>RequestLoggingFilter<span class=\"token operator\">></span> <span class=\"token operator\">=</span> FilterRegistrationBean<span class=\"token operator\">&lt;</span>RequestLoggingFilter<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>\n            <span class=\"token function\">RequestLoggingFilter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">)</span>\n        filterRegistrationBeanRequest<span class=\"token punctuation\">.</span><span class=\"token function\">setName</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"RequestLoggingFilter\"</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> filterRegistrationBeanRequest\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<br/>\n<p>이때 아래와 같이 ‘open’ 키워드를 사용하라는 오류가 발생한다.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/c45c7/001-13.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 38.75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABUklEQVQoz42R607CQBCF+zRKa2IqF+kixV52t3egBVoKFMLF+P5PcBwWjIaY4I8vM+fMTjKzo7lDE77HMGBtmOYLeq99dLpdokf6GbreIvRr/M7/0joMw4DGuiYCyRFKH47rQIYRfC7gCwHXHYFZfVgK6wJjCsasH19phj7lWqf9iDjLUG0/UW6OqDYHlOsdquaI5fbMiWqnS9zsUW8a1Ksay2av/PPbZU16tcK0KKD1TB0+TRhNcgTZBDKdgMdENFaIZEpeAUHeGRklRAwRZaom4rHyRBgrX3toGRDcRjXjqOYSZSExSSOMiwWS6YwaU7gigCfDK9EvbnUEzTB02O8+4nyNaf2BbL7FeNEgXezAaYLbhnto50t5QUL/d0BeNUjyUq0SZDMEaY4woZXiDDxM/oVmPOmwbEeN7/ocHl3Y8S7R9QVFieHIgTUYwnqz7/IFQOAfBtRnGCMAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 13\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/d9199/001-13.png\"\n        srcset=\"/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/8ff5a/001-13.png 240w,\n/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/e85cb/001-13.png 480w,\n/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/d9199/001-13.png 960w,\n/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/c45c7/001-13.png 1346w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<p>코틀린에서는 기본적으로 클래스에는 <code class=\"language-text\">final</code> 키워드가 추가되며, 상속이 불가능하도록 되어있는데,<br>\nSpring Boot 2.x 버전부터는 CGLIB Proxy 방식으로 Bean을 관리하고 있다. CGLIB Proxy는 Target Class를 상속받아 생성하기 때문에 <code class=\"language-text\">open</code> 으로 상속이 가능한 상태이어야 한다.<br>\n때문에 <code class=\"language-text\">all-open</code> 플러그인이 필요하다.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/b4098/001-14.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 816px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 40.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA2UlEQVQoz3WS2QqEMAxF/f/v80lwxRdR3PctMydQ6XRmAuXGak5ubD15x33fiMzzLMuy6CK3YxxHGYZBwjAU3/clCAKpqkratn3qUc88HMehkL7vH52m6WmQJInkeS5FUSiY9+x3XSfneX4Dr+tSFwZCwbZtsu+7LpwARNkHRE7zD4f2yBQCBIxjNwCUZanfG+d2/YdDV01uFsG4uDTNfwLdDRdidF1XdRhFkYJR4Ez0BbTDhZm8rmsFpmkqcRxLlmV6OE3T6P//C/wH5xC4MkA5VUbGNVAb+AJ5yXBAHUEhywAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 14\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/b4098/001-14.png\"\n        srcset=\"/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/8ff5a/001-14.png 240w,\n/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/e85cb/001-14.png 480w,\n/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/b4098/001-14.png 816w\"\n        sizes=\"(max-width: 816px) 100vw, 816px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>참고)<br>\n<a href=\"https://kotlinlang.org/docs/all-open-plugin.html#command-line-compiler\">All-open compiler plugin | Kotlin</a><br>\n<a href=\"https://jaeyeong951.medium.com/kotlin-class-%EC%82%AC%EC%9A%A9%EB%B2%95-24ee79062a96\">[kotlin] class 사용법</a></p>\n<br/>\n<br/>\n<p>build.gradle.kts 의 subprojects/ apply 블럭 내에 kotlin-spring 플러그인을 추가해준다.<br>\n(kotlin-allopen 와 동일)</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/46115/001-15.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 37.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABUUlEQVQoz22Sy07DMBBF8zfgt53YcZzQR+iDik1ViQUbJPao/AH8+mXspq2ALo7H48h37oxTzRYj5stHxNQjtRZdFxFjpNhBaw2l1AUhBDjnfxDl/PytykLjaou69YhtU4RSSoUQWngfCI9AUUoFxthJiE2C4ix4Eq9yUtOF2W7EkkipRd8PaCOJxQaeiuQYOo86ODhvYJyGbQyslZCcUZGr0ypXlFpifdhhe9igTx7DQIJtgKklXNBooqEODEJyRE3Cls5cyRsaU+M1tJpaFrRoYzDun7HaPyH1HfphTg47WE+XIznzjmZoIAilFaSSBaVlyXOUU+uVI/s+Dnh4+UI8fCOs35FWr6jHN4jNEXJ7BF9nPmj/CRsWsCRirYUxV3KeqZTLFTSkTQVhaPjGQ+gAbuIFYTNdcZndSClvUnExvRa7O8HvCXaK7Ab/fpvf/AAY2P2JP9OiYwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 15\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/d9199/001-15.png\"\n        srcset=\"/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/8ff5a/001-15.png 240w,\n/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/e85cb/001-15.png 480w,\n/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/d9199/001-15.png 960w,\n/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/46115/001-15.png 1290w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<br/>\n<h3>2. 각 api 모듈에 controller 생성 후 테스트</h3>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/e0577/001-16.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 37.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABUElEQVQoz22Sa26DMBCEuQ5+Y/wmgZBGrXr/A03HEEVVlB+fjLX27MyaYbt/Y79/YX38ol13xFxIRm4L9scPvm4r7vsNt/sDuTakUjGHCGMtcU88rPNwk8cQZ4/sLeZUEEg/7OcA5z1CzCjeIM7uaBRiOnDTBCkllFJEHvS9EBJDngw6MTfUdsFy3VDqgpQrJh/QvMJM8VwvaJcVdbke5+rS9xtay9jWEbUICgsKJosSFQUcO1tobY7OPcqc6DAp5MSG0cEyplL66Uz9+xanU7ocYnBIQXM2gXFnGKMgxhHaWIRSkOgw5wkxBXg6lXJkNPGGfDEo4+hQ4LFqXNqE1AqdGgqfglorrE2yztGwaWa9O+qX+9zeGcwRQyBYxUiM6hhZy9MhIysKWu6DU9BWw7LZ+QDiI0M4YnYRTTdPOJeJv0BMfFFnj9qrrs613/nEHydA/C7PJi+QAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 16\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/d9199/001-16.png\"\n        srcset=\"/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/8ff5a/001-16.png 240w,\n/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/e85cb/001-16.png 480w,\n/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/d9199/001-16.png 960w,\n/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/07a9c/001-16.png 1440w,\n/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/e0577/001-16.png 1796w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p><strong>api-server1, api-server2 모두 테스트시에 logging이 되지 않는다. 왜?</strong></p>\n<br/>\n<br/>\n<h3>3. ComponentScan 설정</h3>\n<p>프로젝트가 실행되면서 component scan을 하게되는데, 별도로 ComponentScan 관련 설정을 하지 않으면 @SpringBootApplication 이 정의된 곳이 base package 가 된다.</p>\n<p>따라서 각 <code class=\"language-text\">@SpringBootApplication</code> 가 설정되어 있는 클래스에 ComponentScan 설정을 해줘야 한다.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/00e09/001-17.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 32.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABCklEQVQY022Q/U4DIRDE73E8ju8Fehy1pk3T1hh9/7cZB9pUY/xjAmF/zOzudLx+4Xz9wOV6w+n2iW1/oF6xqxuipKEggsPxPJj3y4n8De3whto6155c1+SDIFgDrxVmpTHPMxQ1/5FxHqFLs778w73cz6m0ypSAfVNobcG2eUiKMMbAWA3rDDTDPNPrPqFtimznHFKOsNY+OWMWTJmGpQTUYmicsHLUlWNYdr3QSBNa1AyfWNsyaia3Cpk6OO/d4LqpXhSmmAsfPcGAslbksuOHFTkLHEd0zo1ufeRqJGJNfoQm/utcKQnO3znnLCZhIcaAEAKXKrzHh+ShOLoIvAvrPfyHk1/qHh7fSGy/Kh4gRK0AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 17\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/d9199/001-17.png\"\n        srcset=\"/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/8ff5a/001-17.png 240w,\n/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/e85cb/001-17.png 480w,\n/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/d9199/001-17.png 960w,\n/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/07a9c/001-17.png 1440w,\n/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/00e09/001-17.png 1854w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<p>다시 테스트를 해보면 api-server1, api-server2 모두 logging 되는것을 확인 할 수 있다.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/c7bb6/001-18.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 21.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA4UlEQVQY002Oy07DMBBF8y3gCAglTdM8HNtxHDtFFa8gUbHg///jMFFZsDi6c0czdyZbXldObxeeX1bS+Z0xLoR0xscTdkoYofeRbkPq/2jpbTNuvs66sJA5azHGcNWeun2irTp2u0eK4gGtNUXToPoeZQ1KvDIDt0JZ14yy5/2Ic5YwebIpBGl4QpjxwdMMB/TRogdNnCNuHLnXW5gldw4lXknAnYRV1Z55nv+IpJTItg96ub6plsXDsaTeN7RtK1cdXdeR2w9upm/57It8uAiizUrRf9LGH2qdJLxkX1X8AnZ4hjNOyuJ2AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 18\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/d9199/001-18.png\"\n        srcset=\"/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/8ff5a/001-18.png 240w,\n/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/e85cb/001-18.png 480w,\n/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/d9199/001-18.png 960w,\n/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/07a9c/001-18.png 1440w,\n/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/29114/001-18.png 1920w,\n/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/c7bb6/001-18.png 1986w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/19bb3/001-19.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 22.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAABAklEQVQY011Qy07DMBDMpyBIqpKSEtux4+c6DxqQOCIhATf+/x+GddoTh/FY65n17FbL9o71ZcNle0NYZqTpgkArxpiZJziGDAmq8A0qZQwuwPoImlf2LKACvleRBYkIU2aRFRgHCykkTk8nGK1hvMdRD3gM/gp/Y35TXC++zH6iBEoJlbMWIQRGhNAdtDTonwXatoVSCmq0qIcBjXNoWFtQc9OauZcSKUYkbnTtEVCVoxRSIsjxDKNGKKlAmfafhTFotMGhNHQeDesPzMeug+gFT5d3P+0piROy8H/CMnJZQ04BZ7fgbv7BPaOOX3iI3zvX+gNd+IR7/eV9rhyih+DEf4oapio/j8+sAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 19\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/d9199/001-19.png\"\n        srcset=\"/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/8ff5a/001-19.png 240w,\n/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/e85cb/001-19.png 480w,\n/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/d9199/001-19.png 960w,\n/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/07a9c/001-19.png 1440w,\n/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/29114/001-19.png 1920w,\n/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/19bb3/001-19.png 2066w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<br/>\n<p>참고)</p>\n<ul>\n<li><a href=\"https://bokyung.dev/2022/03/23/kotlin-gradle-querydsl/\">Kotlin + SpringBoot + JPA + Querydsl 멀티 모듈 프로젝트 설정하기</a></li>\n<li><a href=\"https://devs0n.tistory.com/m/50\">Kotlin Gradle Multi Module 적용하기</a></li>\n<li><a href=\"https://lannstark.tistory.com/149\">[Kotlin + Spring Boot + Querydsl] gradle multi project 구성하기</a></li>\n<li><a href=\"https://velog.io/@soyeon207/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-%EB%A9%80%ED%8B%B0-%EB%AA%A8%EB%93%88-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0\">[Spring] 멀티 모듈 프로젝트 만들기</a></li>\n</ul>","fields":{"tagSlugs":["/tags/spring/"],"slug":"/works/posts/2022-07-23--001"},"frontmatter":{"title":"Spring + Kotlin 멀티모듈 생성","tags":["spring"],"date":"2022-07-23","description":""}}},"pageContext":{"slug":"/works/posts/2022-07-23--001"}},"staticQueryHashes":[]}