๐Ÿ๏ธ Spring

๋ฌธ์ œ ์ƒํ™ฉ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.. TestEntity @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity public class TestEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "test_id") private Long id; private String name; } TestRepository public interface TestRepository extends JpaRepository { } TestService @Service @RequiredArgsConstructor @Transactional pu..
์˜ค๋Š˜์€ Redis๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์บ์‹œ๋ฅผ ์ ์šฉํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์ด๋ฒˆ์ด Redis๋ฅผ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฑฐ๋ผ... ์‚ด์ง์€ ๊ณต๋ถ€์šฉ์œผ๋กœ ์ž‘์„ฑํ•œ๊ฑฐ๋ผ ๋งŽ์ด ์ด์ƒํ• ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€๋กœ... ์ง€๊ธˆ ๋ ˆ๋””์Šค๋ฅผ ์ด๊ณณ์ €๊ณณ์— ์ ์šฉํ•ด ๋ณด๋ ค ํ•˜์˜€์œผ๋‚˜.. ์ œ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋„ˆ๋ฌด ์—‰๋ง์œผ๋กœ ์งœ์„œ ๊ทธ๋Ÿฐ์ง€... ์ ์šฉํ•˜๋ ค๋ฉด ๋ฌด์–ธ๊ฐ€ ๋Œ€๋Œ€์ ์ธ ์ˆ˜์ • ์ž‘์—…์ด ํ•„์š”ํ•ด ๋ณด์ด๋”๊ตฐ์š”... ๊ทธ๋ž˜์„œ ์ผ๋‹จ์€... ๋„ค.. ๋ญ ๋กœ๊ทธ์ธ ์‹œ์—๋งŒ ์ ์šฉํ•˜๋„๋ก ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค..^^ ๊ฒŒ๋‹ค๊ฐ€ ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋Š”... ์บ์‹œ๋ฅผ ์ ์šฉํ•˜๋Š” ์ˆœ๊ฐ„ ๋ฉธ๋งํ•ด ๋ฒ„๋ ธ๋Š”๋ฐ, ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ๋ ˆ๋””์Šค๋ฅผ ์ ์šฉํ•˜์ง€ ์•Š์œผ๋ ค๊ณ  ์˜จ๊ฐ– ๋ฐฉ๋ฒ•์„ ๋‹ค ์จ๋ดค์œผ๋‚˜ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค... ํ˜น์‹œ ์—ฌ๊ธฐ์„œ ์ €์™€ ๊ฐ™์ด ๋ ˆ๋””์Šค๋กœ ์บ์‹œ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์„ ๋”ฐ๋ผํ•˜์‹ ๋‹ค๋ฉด... ํ…Œ์ŠคํŠธ์ฝ”๋“œ ๋Œ๋ฆด ๋•Œ๋Š” ๋นผ๊ณ  ๋Œ๋ฆฌ๋Š” ๊ฒƒ์œผ๋กœ...ใ… ใ… ใ…  ๋‚˜์ค‘์— ๊ผญ ๊ณ ์ณ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค..ใ… ..
์ด์ „๊นŒ์ง€์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ํฌ์ŠคํŒ…์—์„œ๋Š” API ๋ฐฉ์‹์ด ์•„๋‹Œ ๊ธฐ๋ณธ์ ์ธ ํ™”๋ฉด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ์‹์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๋‹ค๋ฃจ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ API ํ†ต์‹ ์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ, ํ™”๋ฉด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ์•„๋ฌด๋Ÿฐ ์“ธ๋ชจ๊ฐ€ ์—†๋‹ค. ๋”ฐ๋ผ์„œ API ํ†ต์‹ ์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ค ์‹์œผ๋กœ ์˜ˆ์™ธ ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ •ํ•˜๊ณ , ๊ทธ์— ๋งž๊ฒŒ json์œผ๋กœ ์˜ˆ์™ธ ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” BasicErrorController๋ฅผ ํ†ตํ•ด ๊ธฐ๋ณธ์ ์ธ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค๊ณ  ํ–ˆ์—ˆ๋‹ค. API ์˜ˆ์™ธ ๋˜ํ•œ ์ด๊ณณ์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด ์ฃผ๋Š”๋ฐ, ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” json์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹์ด๋‹ค. Accept ํ—ค๋”๊ฐ€ application/json์ธ ๊ฒฝ์šฐ { "timestamp": "2022-01-07T13:17:21..
์–ด์šฐ ๋˜๊ฒŒ ์˜ค๋žœ๋งŒ์— ๊ธ€ ์“ฐ๋„ค์š”..ใ…Žใ…Ž AOP ๊ณต๋ถ€ํ•˜๋‹ค๊ฐ€ ๋Šฆ์—ˆ์Šต๋‹ˆ๋‹ค... ์•„๋งˆ ์ด๋ฒˆ ํฌ์ŠคํŒ… ์ดํ›„๋กœ ํ•œ๋™์•ˆ ํฌ์ŠคํŒ…์„ ๋ชป ํ•  ๊ฑฐ ๊ฐ™๋„ค์š”... ํ•™๊ต๋„ ๋ณตํ•™ํ•˜๊ณ , ํšŒ์žฅ์ด ๋˜๋ฒ„๋ ค์„œ ์ข€ ์ด๊ฒƒ์ €๊ฒƒ ๋ฐ”์ฉ๋‹ˆ๋‹ค.. ๊ทธ๋ฆฌ๊ณ  ํ† ๋น„์˜ ์Šคํ”„๋ง๋„ ์ฝ๊ณ , ์ด๊ฒƒ์ €๊ฒƒ ๊ณต๋ถ€ํ•  ๊ฒŒ ๋งŽ์•„์„œ์š”..ใ… ใ…  ์˜ค๋Š˜์€ AOP๋ฅผ ์ ์šฉํ•˜์—ฌ Controller, Service, Repository ๊ณ„์ธต์— ๋Œ€ํ•ด ๋ฉ”์„œ๋“œ๊ฐ€ ์ˆ˜ํ–‰๋˜๋ฉด ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๊ณ , ์ด๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅํ•˜๋„๋ก ๋ฐ”๊ฟ”๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์šด์˜ํ™˜๊ฒฝ๋ณ„ ๋กœ๊ทธ ์ˆ˜์ค€์„ ๋‹ค๋ฅด๊ฒŒ ๋‚จ๊ธฐ๋Š” ๊ฒƒ๋„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค! ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์ด์šฉํ•œ JSON ๋ฐ์ดํ„ฐ๋กœ ๋กœ๊ทธ์ธ (์™„๋ฃŒ) JWT๋ฅผ ์ด์šฉํ•œ ์ธ์ฆ (์™„๋ฃŒ) ๋„๋ฉ”์ธ, ํ…Œ์ด๋ธ” ์„ค๊ณ„, ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ (์™„๋ฃŒ) ๋Œ“๊ธ€ ์‚ญ์ œ ๋กœ์ง ๊ตฌํ˜„ (์™„๋ฃŒ) ํšŒ์›๊ฐ€์ž… + ์ •๋ณด์ˆ˜์ • ๋“ฑ ํšŒ์› ์„œ๋น„์Šค ๊ตฌํ˜„ (์™„๋ฃŒ) ๊ฒŒ์‹œํŒ ์„œ..
ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ (cross-cutting concerns) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ๋Šฅ์€ ํ•ต์‹ฌ ๊ธฐ๋Šฅ๊ณผ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์˜ํ™” ์˜ˆ๋งค ์• ํ”Œ๋ฆฌ์—์…˜์˜ ๊ฒฝ์šฐ ์˜ํ™”๋ฅผ ์˜ˆ๋งคํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ ๋กœ์ง์ด๊ณ , ์ด๋Ÿฌํ•œ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ๋ณด์กฐํ•˜๊ธฐ ์œ„ํ•ด ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธด๋‹ค๋˜์ง€ ํ•˜๋Š” ๊ธฐ๋Šฅ๋“ค์€ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํ•ต์‹ฌ ๊ธฐ๋Šฅ๊ณผ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์€ ๊ฐ™์ด ์‚ฌ์šฉ๋˜์ง€๋งŒ, ํ•˜๋‚˜์˜ ์ฝ”๋“œ ์•ˆ์—์„œ ํ•ต์‹ฌ ๊ธฐ๋Šฅ๊ณผ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์ด ๋ชจ๋‘ ๋“ค์–ด๊ฐ€๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋ฉด ํ•ต์‹ฌ ๊ธฐ๋Šฅ์— ์ง‘์ค‘ํ•˜๊ธฐ ์–ด๋ ค์›Œ ์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ๋Œ€๋ถ€๋ถ„์˜ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์€ ํ•˜๋‚˜์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์— ๋ถ™๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์— ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๋„ ๋งŽ์•„์ง‘๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์— ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ(cross-cutting concerns)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์ ..
์ด๋ฒˆ์—๋Š” ๋Œ“๊ธ€์„ ์ €์žฅ, ์ˆ˜์ • ,์‚ญ์ œํ•˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ๋งŒ ๋งŒ๋“ค๋ฉด ๊ทธ๋ž˜๋„ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ๊ฒŒ์‹œํŒ ์„œ๋น„์Šค๋ฅผ ์™„์„ฑํ•˜๋„ค์š”. ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์ด์šฉํ•œ JSON ๋ฐ์ดํ„ฐ๋กœ ๋กœ๊ทธ์ธ (์™„๋ฃŒ) JWT๋ฅผ ์ด์šฉํ•œ ์ธ์ฆ (์™„๋ฃŒ) ๋„๋ฉ”์ธ, ํ…Œ์ด๋ธ” ์„ค๊ณ„, ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ (์™„๋ฃŒ) ๋Œ“๊ธ€ ์‚ญ์ œ ๋กœ์ง ๊ตฌํ˜„ (์™„๋ฃŒ) ํšŒ์›๊ฐ€์ž… + ์ •๋ณด์ˆ˜์ • ๋“ฑ ํšŒ์› ์„œ๋น„์Šค ๊ตฌํ˜„ (์™„๋ฃŒ) ๊ฒŒ์‹œํŒ ์„œ๋น„์Šค ๊ตฌํ˜„ (์ง„ํ–‰ ์ค‘) ๋Œ“๊ธ€ ์„œ๋น„์Šค ๊ตฌํ˜„ (1๋Œ“๊ธ€ -> *(๋ฌดํ•œ) ๋Œ€๋Œ“๊ธ€ ๊ตฌ์กฐ) (์™„๋ฃŒ) ์˜ˆ์™ธ ์ฒ˜๋ฆฌ (์™„๋ฃŒ) ์˜ˆ์™ธ ๋ฉ”์„ธ์ง€ ๊ตญ์ œํ™” ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๊ฒŒ์‹œํŒ ๋ถ„๋ฅ˜ ๊ฒŒ์‹œ๊ธ€ ํŽ˜์ด์ง• (์™„๋ฃŒ) ๋™์ ์ธ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•œ ๊ฒ€์ƒ‰ (์™„๋ฃŒ) ์‚ฌ์šฉ์ž ๊ฐ„ ์ชฝ์ง€ ๊ธฐ๋Šฅ ๋ฌดํ•œ ์ชฝ์ง€ ์Šคํฌ๋กค ๊ฒŒ์‹œ๋ฌผ & ๋Œ“๊ธ€์— ๋Œ€ํ•œ ์•Œ๋žŒ ์ชฝ์ง€์— ๋Œ€ํ•œ ์•Œ๋žŒ ์ ‘์†ํ•œ ์‚ฌ์šฉ์ž ๊ฐ„ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ํšŒ์›๊ฐ€์ž… ์‹œ ..
์ €๋ฒˆ ํฌ์ŠคํŒ…์— ์ด์–ด์„œ ์ด๋ฒˆ์—๋Š” QueryDSL์„ ์‚ฌ์šฉํ•ด์„œ ๊ฒŒ์‹œํŒ ๊ฒ€์ƒ‰(์กฐ๊ฑด์— ๋”ฐ๋ฅธ ๋™์  ๊ฒ€์ƒ‰), ํŽ˜์ด์ง• ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์—ฌ ๊ธฐ๋ณธ์ ์ธ ๊ฒŒ์‹œํŒ์„ ์™„์„ฑ์‹œ์ผœ ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์ด์šฉํ•œ JSON ๋ฐ์ดํ„ฐ๋กœ ๋กœ๊ทธ์ธ (์™„๋ฃŒ) JWT๋ฅผ ์ด์šฉํ•œ ์ธ์ฆ (์™„๋ฃŒ) ๋„๋ฉ”์ธ, ํ…Œ์ด๋ธ” ์„ค๊ณ„, ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ (์™„๋ฃŒ) ๋Œ“๊ธ€ ์‚ญ์ œ ๋กœ์ง ๊ตฌํ˜„ (์™„๋ฃŒ) ํšŒ์›๊ฐ€์ž… + ์ •๋ณด์ˆ˜์ • ๋“ฑ ํšŒ์› ์„œ๋น„์Šค ๊ตฌํ˜„ (์™„๋ฃŒ) ๊ฒŒ์‹œํŒ ์„œ๋น„์Šค ๊ตฌํ˜„ (์ง„ํ–‰ ์ค‘) ๋Œ“๊ธ€ ์„œ๋น„์Šค ๊ตฌํ˜„ (1๋Œ“๊ธ€ -> *(๋ฌดํ•œ) ๋Œ€๋Œ“๊ธ€ ๊ตฌ์กฐ) (์™„๋ฃŒ) ์˜ˆ์™ธ ์ฒ˜๋ฆฌ (์™„๋ฃŒ) ์˜ˆ์™ธ ๋ฉ”์„ธ์ง€ ๊ตญ์ œํ™” ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๊ฒŒ์‹œํŒ ๋ถ„๋ฅ˜ ๊ฒŒ์‹œ๊ธ€ ํŽ˜์ด์ง• (์ง„ํ–‰ ์ค‘) ๋™์ ์ธ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•œ ๊ฒ€์ƒ‰ (์ง„ํ–‰ ์ค‘) ์‚ฌ์šฉ์ž ๊ฐ„ ์ชฝ์ง€ ๊ธฐ๋Šฅ ๋ฌดํ•œ ์ชฝ์ง€ ์Šคํฌ๋กค ๊ฒŒ์‹œ๋ฌผ & ๋Œ“๊ธ€์— ๋Œ€ํ•œ ์•Œ๋žŒ ์ชฝ์ง€์— ๋Œ€ํ•œ ์•Œ๋žŒ ์ ‘์†ํ•œ ์‚ฌ์šฉ์ž ๊ฐ„ ..
์˜ค๋žœ๋งŒ์— ๊ธ€์„ ์“ฐ๋Š” ๊ฑฐ ๊ฐ™๋„ค์š”.. ๋ฆฌ๋ˆ…์Šค๋ž‘ ๋ญ ์ด๊ฒƒ์ €๊ฒƒ ๊ณต๋ถ€ํ•œ๋‹ค๊ณ  ๋ฐ”๋ป์„œ...ใ… ใ…  ์˜ค๋Š˜์€ QueryDSL์„ ์‚ฌ์šฉํ•ด์„œ ๊ฒŒ์‹œํŒ ๊ฒ€์ƒ‰(์กฐ๊ฑด์— ๋”ฐ๋ฅธ ๋™์  ๊ฒ€์ƒ‰), ํŽ˜์ด์ง•, ์กฐํšŒ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์—ฌ ๊ธฐ๋ณธ์ ์ธ ๊ฒŒ์‹œํŒ์„ ์™„์„ฑ์‹œ์ผœ ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์ด์šฉํ•œ JSON ๋ฐ์ดํ„ฐ๋กœ ๋กœ๊ทธ์ธ (์™„๋ฃŒ) JWT๋ฅผ ์ด์šฉํ•œ ์ธ์ฆ (์™„๋ฃŒ) ๋„๋ฉ”์ธ, ํ…Œ์ด๋ธ” ์„ค๊ณ„, ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ (์™„๋ฃŒ) ๋Œ“๊ธ€ ์‚ญ์ œ ๋กœ์ง ๊ตฌํ˜„ (์™„๋ฃŒ) ํšŒ์›๊ฐ€์ž… + ์ •๋ณด์ˆ˜์ • ๋“ฑ ํšŒ์› ์„œ๋น„์Šค ๊ตฌํ˜„ (์™„๋ฃŒ) ๊ฒŒ์‹œํŒ ์„œ๋น„์Šค ๊ตฌํ˜„ (์ง„ํ–‰ ์ค‘) ๋Œ“๊ธ€ ์„œ๋น„์Šค ๊ตฌํ˜„ (1๋Œ“๊ธ€ -> *(๋ฌดํ•œ) ๋Œ€๋Œ“๊ธ€ ๊ตฌ์กฐ) (์™„๋ฃŒ) ์˜ˆ์™ธ ์ฒ˜๋ฆฌ (์™„๋ฃŒ) ์˜ˆ์™ธ ๋ฉ”์„ธ์ง€ ๊ตญ์ œํ™” ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๊ฒŒ์‹œํŒ ๋ถ„๋ฅ˜ ๊ฒŒ์‹œ๊ธ€ ํŽ˜์ด์ง• (์ง„ํ–‰ ์ค‘) ๋™์ ์ธ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•œ ๊ฒ€์ƒ‰ (์ง„ํ–‰ ์ค‘) ์‚ฌ์šฉ์ž ๊ฐ„ ์ชฝ์ง€ ๊ธฐ๋Šฅ ๋ฌดํ•œ ์ชฝ์ง€ ์Šคํฌ๋กค..
๋ง ๋ž‘
'๐Ÿ๏ธ Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๊ธ€ ๋ชฉ๋ก (9 Page)