4 min read

[Spring ๊ณต๋ถ€] ์ด์ œ์„œ์•ผ Spring์„ ๊ณต๋ถ€ํ•˜๊ฒŒ ๋œ ์ด์œ 

Table of Contents

์™œ ์ด์ œ์•ผ?

๋Œ€ํ•œ๋ฏผ๊ตญ์ด๋ผ๋Š” ํ™˜๊ฒฝ์—์„œ Java์™€ Spring์€ ๊ต‰์žฅํžˆ ๋ง‰๊ฐ•ํ•œ ์‹œ์žฅ ์ ์œ ์œจ์„ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ๋‹ค. ์‚ฌ์‹ค์ƒ ๋Œ€๋ถ€๋ถ„์˜ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ๊ตฌ์ธ๋„ Spring์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฃจ์–ด์ง€๊ณ  ์žˆ์„ ๋งŒํผ, ์ทจ์—…์„ ์ค€๋น„ํ•˜๋Š” ์ž…์žฅ์—์„œ Spring์„ ๋Šฅ์ˆ™ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํ•„์ˆ˜ ์—ญ๋Ÿ‰์— ๊ฐ€๊นŒ์šด ๋ฌด์–ธ๊ฐ€๊ฐ€ ๋˜์–ด๊ฐ€๊ณ  ์žˆ๋‹ค.

๋‚˜๋„ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋ฅผ ์ง€๋งํ•˜๊ณ  ์žˆ๋‹ค ๋ณด๋‹ˆ, ์ด๋Ÿฌํ•œ ์ƒํƒœ๊ณ„์™€ ๊ตญ๋‚ด ํ™˜๊ฒฝ์— ๋Œ€ํ•ด ์ตํžˆ ๋“ค์–ด ์•Œ๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ์ง€๊ธˆ์— ์™€์„œ์•ผ Spring์„ ๊ณต๋ถ€ํ•˜๊ธฐ ์‹œ์ž‘ํ•œ ๊ฒƒ์€ ์‚ฌ์‹ค Java๋ฅผ ๋ฉ€๋ฆฌ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ, ๊ทธ ์ด์œ ๊ฐ€ ์ฐธ ๊ฐ€์†Œ๋กญ๋‹ค.

๋‚˜๋Š” 2017๋…„์— ๋Œ€ํ•™์— ์ž…ํ•™ํ•ด์„œ C ์–ธ์–ด๋ฅผ ๋ฐฐ์šฐ๋ฉฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์ž…๋ฌธํ–ˆ๊ณ , 2018๋…„์— ํ•™๊ต์—์„œ ์ฒ˜์Œ์œผ๋กœ Java๋ฅผ ๋ฐฐ์› ๋‹ค. ๊ทธ ๋‹น์‹œ์—๋Š” ์•Œ๊ณ  ์žˆ๋˜ ์–ธ์–ด๊ฐ€ C ๋ฐ–์— ์—†์—ˆ์œผ๋‹ˆ Java๋Š” ๋„ˆ๋ฌด ๋ฉ‹์ง„ ์–ธ์–ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ 2019๋…„์ด ๋˜์–ด Python๊ณผ Javascript๋ฅผ ์•Œ๊ฒŒ ๋˜๋ฉด์„œ ์—ฌ๋Ÿฌ๋ชจ๋กœ ์ƒ๊ฐ์ด ๋ณต์žกํ•ด์กŒ๋‹ค. ๊ทธ ๋•Œ ๋ฌธ๋“ ํ•˜๊ฒŒ ๋œ ์ƒ๊ฐ์€ โ€œ์•„โ€ฆ ๋ญ˜๊นŒ ์ด ์–ธ์–ด, C++๋ณด๋‹ค๋Š” ๋А๋ฆฌ๋ฉด์„œ Python์ด๋‚˜ Javascript์— ๋น„ํ•ด์„œ๋Š” ์ฝ”๋“œ๊ฐ€ ๋ชป์ƒ๊ธดโ€ฆ ๋ญ”๊ฐ€ ๋ฉ‹์ง€์ง€ ์•Š์€๊ฑธ?โ€ ์ด์—ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ๋กœ ๋ฐฐ์šด ์–ธ์–ด์ด๋‹ค ๋ณด๋‹ˆ ๊ณ ๋ฆฌํƒ€๋ถ„ํ•˜๋‹ค๊ณ ๋„ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ์ด๋Ÿฐ ๋ง๋„ ์•ˆ๋˜๋Š” ์ด์œ ๋กœ ๊ทธ๋ƒฅ Java ์ชฝ์œผ๋กœ๋Š” ์ ˆ๋Œ€ ๋ˆˆ๊ธธ์„ ์ฃผ์ง€ ์•Š์•˜๋‹ค.

์ง€๊ธˆ ์™€์„œ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๊ฐ•๋ ฅํ•œ GC์™€ OOP ํŒจ๋Ÿฌ๋‹ค์ž„, ๊ทธ๋ฆฌ๊ณ  ์œ ๊ตฌํ•œ ์—ญ์‚ฌ์™€ ์ „ํ†ต์„ ๊ฐ€์ง€๊ณ  ์ˆ™์„ฑ๋œ ๋งˆ์น˜ ์ˆ ๋กœ ๋”ฐ์ง€์ž๋ฉด ๋กœ์–„ ์‚ด๋ฃจํŠธ 32๋…„์‚ฐ๊ณผ ๊ฐ™์€ ๊ฑฐ๋Œ€ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ธ Spring์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ต‰์žฅํžˆ ๋Œ€๋‹จํ•œ ์–ธ์–ด๋ฅผ ๊ทธ๋ƒฅ ๊ธธ๋ฐ”๋‹ฅ์— ๊ตด๋Ÿฌ๋‹ค๋‹ˆ๋Š” ๋Œ๋งน์ด ์ •๋„๋กœ ์ทจ๊ธ‰ํ•œ ๊ฒƒ์ด์ง€๋งŒ, ๊ทธ ๋• ๊ทธ๋Ÿฐ ์‚ฌ์‹ค์„ ์•Œ๊ธฐ์— ๋„ˆ๋ฌด๋‚˜๋„ ๋‚ด ์‹๊ฒฌ์ด ์–•์•˜๋‹ค. (์ง€๊ธˆ์ด๋ผ๊ณ  ๊นŠ์€ ๊ฒƒ ๊ฐ™์ง€๋„ ์•Š์ง€๋งŒ)

Java๋ฅผ ๋ฉ€๋ฆฌ ํ•˜๋‹ค ๋ณด๋‹ˆ, Spring์„ ๊ณต๋ถ€ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๋ง๋„ ์•ˆ๋˜๋Š” ์ผ์ด์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ง€๊ธˆ๊ป ํ•ญ์ƒ Spring์„ ๊ณต๋ถ€ํ•˜๋Š” ๊ฒƒ์€ ๊ตฐ๋Œ€๋ฅผ ์ „์—ญํ•˜๊ณ  ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ ์ทจ์—…์„ ์ค€๋น„ํ•˜๋Š” ์นœ๊ตฌ๋“ค์—๊ฒŒ ์ถ”์ฒœํ• ์ง€์–ธ์ •, ์Šค์Šค๋กœ ๊ณต๋ถ€ํ•ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์€ ํ•˜์ง€ ์•Š์•˜๋‹ค.

์ด์ œ ์™€์„œ๋Š” ์™œ?

๊ทธ ์ดํ›„๋กœ ์„œ๋ฒ„๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•  ์ผ์ด ์ƒ๊ธธ ๋•Œ๋งˆ๋‹ค ๋Œ€๋ถ€๋ถ„ node.js ๋ฅผ ํ†ตํ•ด์„œ ์„œ๋ฒ„๋ฅผ ๊ฐœ๋ฐœํ–ˆ๋‹ค. Javascript์˜ ๊ฐ„๊ฒฐํ•œ ๋ฌธ๋ฒ•๋„ ๋งˆ์Œ์— ๋“ค์—ˆ๊ณ , ์กฐ๊ธˆ ๋‹ค๋ฅธ ์ด์•ผ๊ธฐ์ด๊ธด ํ•˜์ง€๋งŒ ์• ํ”Œ์˜ ์ฒ ํ•™์ฒ˜๋Ÿผ, โ€œ๊ทธ๋ƒฅ ๋จโ€ ์ด๋ผ๋Š” ๋А๋‚Œ์„ ๋ฐ›๋Š” ๊ฒƒ๋„ ๋„ˆ๋ฌด ์ข‹์•˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํƒ€์ž… ์ถ”๋ก ์— ์žˆ์–ด์„œ ์•ฝ๊ฐ„์˜ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋Š” ๋ถ€๋ถ„์„ Typescript๋ผ๋Š” ๋ฉ‹์ง„ Superset์„ ํ†ตํ•ด์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์‚ฌ์‹ค์ƒ ์ด๊ฑธ๋กœ ๋‹ค ํ•ด๋จน์„ ์ˆ˜ ์žˆ๊ฒ ๋‹ค๋ผ๋Š” ์ƒ๊ฐ๊นŒ์ง€ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋‹ค. (์‚ฌ์‹ค ๋‹ค ํ•ด๋จน์„ ์ˆ˜ ์žˆ๊ฒ ๋‹ค๋Š” ์ด ์ƒ๊ฐ์€ ์ง€๊ธˆ๊นŒ์ง€๋„ ์œ ํšจํ•˜๋‹ค.)

๊ทธ๋ ‡์ง€๋งŒ ํ•ญ์ƒ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ๋ฅผ ๋”ฐ๋ผ์„œ ์ž‘์„ฑํ•˜๊ณ  ํ”„๋กœ์ ํŠธ์˜ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ •ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ํ•  ๋•Œ๋งˆ๋‹ค ๋ญ”๊ฐ€ ๋งˆ์Œ ํ•œ์ผ ์ด ๋ถˆํŽธํ–ˆ๋‹ค.

โ€œ์ด๊ฒŒ ์ง„์งœ ์ œ์ผ ๋‚˜์€ ํŒจํ„ด์ผ๊นŒ?โ€

โ€œ์ด ํŒจํ„ด์„ ๋‚ด๊ฐ€ ์ œ๋Œ€๋กœ ์ง€์ผœ๊ฐ€๋ฉด์„œ ์ž‘์„ฑํ•˜๊ณ  ์žˆ์„๊นŒ?โ€

์–ด์งธ์ €์งธ ์—๋Ÿฌ๊ฐ€ ํ„ฐ์ง€๋ฉด ๋•Œ์šฐ๊ณ  ๊ธฐ์šฐ๊ณ  ๋ฎ์–ด๊ฐ€๋ฉฐ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜๋Š” ์žˆ์—ˆ์ง€๋งŒ ๋‚ด๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๊ณ ์žˆ๋‹จ ์ƒ๊ฐ๊ณผ, ์ด ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด์˜ ๊ทœ์น™์„ ์ถฉ์‹คํžˆ ๋”ฐ๋ฅด๊ณ  ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  2020๋…„์ด ๋˜์–ด, ํ•œ ๋ฉ‹์ง„ node.js ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งŒ๋‚˜๊ณ  ๊ทธ ํ•ด๋‹ต์„ ์ฐพ์€ ๊ฒƒ๋งŒ ๊ฐ™์•˜๋‹ค. ๊ทธ๊ฒƒ์€ ๋ฐ”๋กœ NestJS ์˜€๋‹ค. Module, Controller, Service๋กœ ๋ ˆ์ด์–ด๋ฅผ ๋‚˜๋ˆ„์–ด์„œ ๊ทธ ๊ตฌ์กฐ์— ๋งž์ถ”์–ด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ๊ณผ, ์ ์ •์„ ์—์„œ Decorator Function์„ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ ๋“ฑ ์ •๋ง ๋งˆ์Œ์— ๋“œ๋Š” ์ ์ด ๋งŽ์•˜๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, ์–ด๋–ค ์ปค๋ฎค๋‹ˆํ‹ฐ(์ •ํ™•ํžˆ ์–ด๋””์˜€๋Š”์ง€ ๊ธฐ์–ต์ด ์ž˜ ๋‚˜์ง€ ์•Š๋Š”๋‹ค.)์—์„œ โ€œ์†”์งํžˆ Nest ํ•  ๋ฐ”์— Spring ํ•˜๊ณ  ๋ง์ง€ ใ„นใ…‡ใ…‹ใ…‹โ€ ๋ผ๋Š” ๋ง์„ ํ•˜๋Š” ๊ฒƒ์„ ๋ดค๊ณ , Spring์˜ ๊ธฐ๋ณธ ์ปจ์…‰์„ ์ฐพ์•„๋ณด๊ณ  ๋‚˜์„œ IoC์™€ DI ๋“ฑ์ด Nest์™€ ๊ต‰์žฅํžˆ ์œ ์‚ฌํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ์ € ๋ง์€ Opnionated Framework (๋А๋‚Œ์„ ๋ฒˆ์—ญํ•ด๋ณด์ž๋ฉด, ์™„์ „ ๊ด€๋ฆฌํ˜• ํ”„๋ ˆ์ž„์›Œํฌ ์ •๋„)๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๋ฉด ์™œ ๊ตณ์ด node.js๋ฅผ ์‚ฌ์šฉํ•˜๋ƒ๋ผ๊ณ  ๋น„๊ผฌ๋Š” ์–ด์กฐ์˜€๋‹ค.

์ •๋ณด๋ฅผ ์กฐ๊ธˆ ๋” ์ฐพ์•„๋ณธ ํ›„ ๋‚˜๋Š” Opinionated Framework๋“ค์˜ ๊ตฌ์กฐ์˜ ํŠน์ง•๊ณผ ์žฅ๋‹จ์ ์„ ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๊ณ  ์žˆ์–ด์•ผ๋งŒ node.js์˜ Express๋‚˜ Python์˜ Flask, Go์˜ echo ๊ฐ™์€ Micro Framework๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋„ ๊ตฌ์กฐ์ ์œผ๋กœ ๋” ์•ˆ์ •์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์›์กฐ ๋ง›์ง‘์ธ Spring์„ ๊ณต๋ถ€ํ•ด์•ผ๊ฒ ๋‹ค๊ณ  ๋งˆ์Œ ๋จน์—ˆ๋Š”๋ฐ, Spring์€ ์›Œ๋‚™ ๊ฐœ๋ฐœ๋œ์ง€ ์˜ค๋ž˜๋˜์—ˆ๊ณ , ์šฐ๋ฆฌ๋‚˜๋ผ์—์„œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด๋ถ€์ ์ด๊ณ  ๊ตฌ์ฒด์ ์ธ ์›๋ฆฌ๊นŒ์ง€ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์„œ์ ์ด๋‚˜ ๊ฐ•์˜๋“ค์„ ํ†ตํ•ด์„œ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด๋ ‡๊ฒŒ ๋’ค๋Šฆ๊ฒŒ๋‚˜๋งˆ ๋‚˜๋Š” Spring์„ ๊ณต๋ถ€ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์‚ฌ์‹ค ์ด๋Ÿฐ ์  ์ด์™ธ์—๋„ ํ˜„์žฌ node.js๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋ฐœ์ž์˜ ์ž…์žฅ์—์„œ Spring์„ ํ•œ๋ฒˆ์ฏค ๊ณต๋ถ€ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ด์œ , ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋ฐ˜๋Œ€๋กœ Spring์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋“ค์ด node.js์— ๋Œ€ํ•ด์„œ ํ•œ๋ฒˆ์ฏค ๊ณต๋ถ€ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ด์œ ๊ฐ€ ๋” ์žˆ๊ธด ํ•œ๋ฐ ๊ทธ๊ฒƒ๋“ค์€ ์ฃผ ๊ณจ์ž๊ฐ€ ์•„๋‹ˆ๊ณ  ์Šค์Šค๋กœ๋„ ์ œ๋Œ€๋กœ ์ •๋ฆฌํ•˜์ง€ ๋ชปํ–ˆ์œผ๋‹ˆ ์ด๋ฒˆ์—” ๋„˜์–ด๊ฐ€๋„๋ก ํ•˜๊ณ , ๋‹ค์Œ์— ๊ธ€๋กœ ํ’€์–ด๋ณด๋Š” ๊ธฐํšŒ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

์–ด์จŒ๊ฑฐ๋‚˜ ์ €์จŒ๊ฑฐ๋‚˜

์•ž์œผ๋กœ 8์ฃผ ๋™์•ˆ์€ Spring Boot ์Šคํ„ฐ๋””๋ฅผ ํ•˜๋‚˜ ๊พธ๋ฆฌ๊ฒŒ ๋˜์–ด, ์Šคํ„ฐ๋””์›๋ถ„๋“ค๊ณผ ํ•จ๊ป˜ Spring์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•  ๊ฒƒ ๊ฐ™๋‹ค. ๋‹ค์–‘ํ•œ ์‹œ๊ฐ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๊ฐ€ ๋  ๊ฒƒ ๊ฐ™์•„ ์—ฌ๋Ÿฌ๋ชจ๋กœ ๊ธฐ๋Œ€๊ฐ€ ๋œ๋‹ค.

๋.