
์น ๊ฐ๋ฐ์ ํ๋ค ๋ณด๋ฉด ๊ผญ ๋ง๋๊ฒ ๋๋ ๊ฐ๋ ์ด ๋ฐ๋ก MVC ํจํด์ ๋๋ค. ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉ์ ๊ฒฝํ์ ๋งค๋๋ฝ๊ฒ ํ๊ธฐ ์ํ ํ์ ๊ตฌ์กฐ์ด๊ธฐ๋ ํ์ฃ . ๊ทธ๋ผ MVC ํจํด์ด ๋ฌด์์ธ์ง, ๊ฐ ๊ตฌ์ฑ ์์๊ฐ ์ด๋ค ์ญํ ์ ํ๋์ง ์์๋ด ์๋ค.
์ ํ๋ฆฌ์ผ์ด์
์ํ์ ์บก์ํ
๋ชจ๋ธ์ ๋ฐ์ดํฐ์ ๋น์ฆ๋์ค ๋ก์ง์ ์ฑ
์์ง๋ฉฐ, ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ์ ์ฅํ๊ณ ๊ด๋ฆฌํฉ๋๋ค. ์ฆ, ์ฌ์ฉ์์ ๋ชจ๋ ์์ฒญ๊ณผ ์ ํ๋ฆฌ์ผ์ด์
๋์์ ์ค์ฌ์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ๋ ์ ์งํด์ผ ํ๊ธฐ์, ์ ํ๋ฆฌ์ผ์ด์
์ ๊ธฐ๋ฐ์ด ๋๋ ์ค์ํ ์ญํ ์ ๋ด๋นํ์ฃ .
์ํ ์ฟผ๋ฆฌ์ ๋ํ ์ฆ๊ฐ์ ์๋ต!
์ฌ์ฉ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ ๋ ๋ชจ๋ธ์ ์ด๋ฅผ ๋น ๋ฅด๊ณ ์ ํํ๊ฒ ๋ฐํํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ์ผํ๋ชฐ์์ ์ ํ ์ ๋ณด๋ฅผ ์์ฒญํ๋ค๋ฉด, ๋ชจ๋ธ์ด ํด๋น ์ ํ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ๋ ์ญํ ์ ํฉ๋๋ค.
๊ธฐ๋ฅ ๊ตฌํ ๋ฐ ์ฒ๋ฆฌ
๋จ์ํ ๋ฐ์ดํฐ๋ง ์ ์ฅํ๋ ๊ฒ ์๋๋ผ, ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง์ ๋ํ ๋
ผ๋ฆฌ๋ ํฌํจํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ฅ๋ฐ๊ตฌ๋์ ๋ด๊ธด ์ํ ๊ฐ๊ฒฉ์ ํฉ๊ณ๋ฅผ ๊ณ์ฐํ๋ ๊ฒ๋ ๋ชจ๋ธ์ ๋ชซ์
๋๋ค.
๋ณ๊ฒฝ ์ ์ฆ์ ๋ทฐ์ ์๋ฆผ
๋ชจ๋ธ์ ์ ์ฅ๋ ๋ฐ์ดํฐ๊ฐ ์
๋ฐ์ดํธ๋๋ฉด, ์ด ๋ณ๊ฒฝ ์ฌํญ์ ๋ทฐ์ ์๋ฆฌ๋ฉด์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์ ์ค์๊ฐ์ผ๋ก ๋ฐ์๋๋๋ก ํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ์ฉ์๋ ์ต์ ์ ๋ณด๋ฅผ ํ๋ฉด์์ ๋ฐ๋ก ํ์ธํ ์ ์์ต๋๋ค.
๋ชจ๋ธ์ ์๊ฐ์ ์ผ๋ก ํํํ๋ ์ต์ ์
๋ทฐ๋ ๋ชจ๋ธ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ฌ์ฉ์๊ฐ ์ฝ๊ฒ ๋ณผ ์ ์๋ ํํ๋ก ๋ณด์ฌ์ค๋๋ค. UI ์์๋ ์น ํ์ด์ง, ์ ํ๋ฆฌ์ผ์ด์
ํ๋ฉด ๋ฑ์ด ๋ชจ๋ ๋ทฐ์ ํด๋นํฉ๋๋ค. ๋ทฐ๋ ํ๋ฉด์ ๋ชจ์๊ณผ ๋์์ธ์ ์ฑ
์์ง๋ฉฐ, ์ฌ์ฉ์ ๊ฒฝํ์ ์ข์ฐํ๋ ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
์ต์ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ๋ฐ์ํ๋ ์ค๋งํธํ ์
๋ฐ์ดํธ
์ฌ์ฉ์๊ฐ ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจํ ๋๋ง๋ค, ๋ทฐ๋ ๋ชจ๋ธ์๊ฒ ์ต์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ์ฌ ์๋กญ๊ฒ ์ ๋ณด๋ฅผ ํ์ํ ์ ์์ต๋๋ค. ์ด๋ก ์ธํด ์ฌ์ฉ์์๊ฒ ์ค์๊ฐ์ผ๋ก ์
๋ฐ์ดํธ๋ ์ ๋ณด๋ฅผ ์ ๊ณตํ์ฃ .
์ฌ์ฉ์์ ๋ชจ๋ ์
๋ ฅ์ ์ปจํธ๋กค๋ฌ๋ก ์ ๋ฌ
๋ทฐ๋ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๋ฐ์ดํฐ๋ฅผ ์ปจํธ๋กค๋ฌ์ ์ ๋ฌํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ํ์๊ฐ์
์์์์ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ์ ๋ณด๋ฅผ ์ปจํธ๋กค๋ฌ์ ๋๊ธฐ๋ ์ญํ ์ ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ๋ฌด์์ ์ํ๊ณ ์๋์ง ์ค์๊ฐ์ผ๋ก ์ดํดํ๋ ๋ทฐ ๋๋ถ์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๊ฐ ๋์ฑ ์ง๊ด์ ์ผ๋ก ๋์ํ ์ ์์ต๋๋ค.
์ปจํธ๋กค๋ฌ์ ์ ํ์ ๋ฐ๋ผ ๋ณํํ๋ ๋ทฐ
๋ทฐ๋ ์ ํ๋ฆฌ์ผ์ด์
๋ก์ง์ ๋ฐ๋ผ ์ปจํธ๋กค๋ฌ๊ฐ ์ด๋ค ํ๋ฉด์ ๋ณด์ฌ์ค์ง ๊ฒฐ์ ํ๊ฒ ๋ง๋ญ๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ๋ฒํผ์ ๋๋ฅด๋ฉด ๋ก๊ทธ์ธ ์ฑ๊ณต ์ ํ ํ๋ฉด์, ์คํจ ์ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ณด์ฌ์ฃผ๋ ํ๋ฉด์ ํ์ํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์์ฒญ์ ๋ฐ์ ์ ํ๋ฆฌ์ผ์ด์
๋์์ ์ ์
์ปจํธ๋กค๋ฌ๋ ์ฌ์ฉ์์ ์ก์
์ ๋ฐ์ ์ ์ ํ ๋์์ ์ ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๊ทธ์ ๋ฐ๋ผ ๋ฐ์ํ๋ ์ด๋ฒคํธ์ ๊ทธ์ ๋ฐ๋ฅธ ๋์์ด ๋ชจ๋ ์ปจํธ๋กค๋ฌ์ ์ํด ์ ์๋ฉ๋๋ค.
์ฌ์ฉ์์ ํ๋์ ๋ชจ๋ธ ์
๋ฐ์ดํธ์ ์ฐ๊ฒฐ
์ฌ์ฉ์๊ฐ ์ด๋ค ์์
์ ํ์ ๋, ๊ทธ์ ๋ง๋ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ธ์ ๋ฐ์ํ๋ ๊ฒ๋ ์ปจํธ๋กค๋ฌ์ ์ญํ ์
๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ์ผํ๋ชฐ์์ ์ ํ์ ์ฅ๋ฐ๊ตฌ๋์ ์ถ๊ฐํ๋ฉด, ๊ทธ ์ ๋ณด๋ฅผ ๋ชจ๋ธ์ ์ ์ฅํ๋๋ก ๋ช
๋ นํฉ๋๋ค.
๊ฒฐ๊ณผ์ ๋ง๋ ๋ทฐ๋ฅผ ์ ํํ์ฌ ์ฌ์ฉ์์๊ฒ ์ ๊ณต
์ปจํธ๋กค๋ฌ๋ ์ฌ์ฉ์์ ์์ฒญ์ ์ฒ๋ฆฌํ ๋ค, ๊ทธ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ์ด๋ค ๋ทฐ๋ฅผ ๋ณด์ฌ์ค์ง ๊ฒฐ์ ํฉ๋๋ค. ๋ก๊ทธ์ธ ์ฑ๊ณต ์ ํ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ฒ๋ผ, ์ฌ์ฉ์์ ํ๋์ ๋ง๊ฒ ๋ทฐ๋ฅผ ์ ํํฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ฅํ๊ณ ์ ์ง๋ณด์ํ๋ ์ผ์ด ์ฝ์ง ์์๋ฐ์, MVC ํจํด์ ์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ณ ์๋ ํจ์จ์ ์ธ ๊ตฌ์กฐ์ ๋๋ค. ์ด๋ฒ์๋ MVC ํจํด์ ํ์ฅ์ฑ, ์ฅ์ ๊ณผ ๋จ์ ์ ๋ํด ๊น์ด ํํค์ณ๋ณด๊ฒ ์ต๋๋ค!
์ ํ๋ฆฌ์ผ์ด์
ํ์ฅ์ ์ํ ๊ตฌ์กฐ์ ๋ถ๋ฆฌ
MVC ํจํด์ Model, View, Controller์ ์ธ ๊ฐ์ง ์์ญ์ผ๋ก ๋๋ฉ๋๋ค. ์ด ์ธ ๊ฐ์ง ๊ตฌ์ฑ ์์๋ฅผ ๋
๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌํจ์ผ๋ก์จ, ์ ํ๋ฆฌ์ผ์ด์
ํ์ฅ ์์๋ ๋ค๋ฅธ ๋ถ๋ถ์ ์ํฅ์ ์ฃผ์ง ์๊ณ ๊ฐ๊ฐ์ ์์๋ฅผ ์ฝ๊ฒ ์์ ํ๊ณ ํ์ฅํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ค๋ฉด ๊ธฐ์กด ๊ตฌ์กฐ๋ฅผ ์ ํ ๊ฑด๋๋ฆฌ์ง ์๊ณ ํ์ํ ๋ถ๋ถ๋ง ์์ ํ ์ ์์ฃ .
๋ณ๊ฒฝ์ด ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ์ํฅ์ ๋ฏธ์น์ง ์์
MVC ํจํด์ ์ฅ์ ์ค ํ๋๋ ํ ์์ญ์ ๋ณ๊ฒฝ์ด ๋ค๋ฅธ ์์ญ์ ์ํฅ์ ๋ฏธ์น์ง ์๋ ๊ฒ์
๋๋ค. ๋ชจ๋ธ์์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฐฉ์์ ๋ณ๊ฒฝํด๋ ํ๋ฉด(View)์ด๋ ์ฌ์ฉ์ ์์ฒญ ์ฒ๋ฆฌ(Controller)์๋ ์ ํ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ์ ์ง๋ณด์๊ฐ ๋งค์ฐ ์ฉ์ดํ๋ฉฐ, ํน์ ๋ถ๋ถ๋ง ์์ ํ๊ณ ์ ํ ๋๋ ๋ถ๋ด์ด ์ ์ต๋๋ค.
๋ฎ์ ๊ฒฐํฉ์ฑ, ๋์ ๋
๋ฆฝ์ฑ
์ปดํฌ๋ํธ ๊ฐ ๊ฒฐํฉ๋๊ฐ ๋ฎ๋ค๋ ๊ฒ์, ๊ฐ ๊ตฌ์ฑ ์์๊ฐ ์๋ก ์์กดํ๋ ์ ๋๊ฐ ๋งค์ฐ ์ ๋ค๋ ์๋ฏธ์
๋๋ค. ์ด๋ ๊ฒ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋ฉด, ํ๋ก๊ทธ๋จ์ ์์ ๊ณผ ์ถ๊ฐ ์์
์ด ํจ์ฌ ์ฌ์์ง๋ฉฐ, ๊ฒฐ๊ณผ์ ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์
์ ํ์ฅ์ฑ์ด ๋ํญ ํฅ์๋ฉ๋๋ค. ์ด์ฒ๋ผ ๊ฒฐํฉ์ฑ์ ๋ฎ์ถ๋ ๊ตฌ์กฐ๋ ๋ํ ํ๋ก์ ํธ์์ ํนํ ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
ํ๋ฉด๊ณผ ๋น์ฆ๋์ค ๋ก์ง์ ๋ถ๋ฆฌํ ๋ณํ ์์
MVC ํจํด์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ค ํ๋๋ ๋น์ฆ๋์ค ๋ก์ง๊ณผ UI๋ฅผ ๋ถ๋ฆฌํ์ฌ ๋
๋ฆฝ์ ์ผ๋ก ์์
ํ ์ ์๋ค๋ ์ ์
๋๋ค. ์ด ๋๋ถ์ ํ๋ก ํธ์๋์ ๋ฐฑ์๋ ๊ฐ๋ฐ์๊ฐ ๋์์ ๊ฐ๋ฐ์ ์งํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, UI ๊ฐ๋ฐ์๋ ํ๋ฉด์ ๊ตฌ์ฑํ๊ณ ๋ฐฑ์๋ ๊ฐ๋ฐ์๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ก์ง์ ๊ตฌํํจ์ผ๋ก์จ ํ ๊ฐ ํ์
์ด ๋์ฑ ์ํํด์ง๋๋ค.
ํ์ฅ์ฑ์ ์ต์ ํ๋ ์์ญ๋ณ ๊ฐ๋ฐ
์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋, ๋ชจ๋ธ๋ง ์์ ํ๊ฑฐ๋ ์ปจํธ๋กค๋ฌ์ ๋ก์ง์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์์ญ๋ณ๋ก ์ง์คํ์ฌ ์์
ํ ์ ์์ต๋๋ค. ๊ธฐ์กด ํ๋ฉด(View)์ ์์ ํ ํ์ ์์ด, ๊ฐ ์์ญ์ด ๋
๋ฆฝ์ ์ผ๋ก ํ์ฅ ๊ฐ๋ฅํ ๊ตฌ์กฐ์ด๊ธฐ ๋๋ฌธ์ ์ ํ๋ฆฌ์ผ์ด์
ํ์ฅ์ด ํจ์ฌ ์์ํฉ๋๋ค.
ํ์คํ๋ ์ฝ๋๋ก ํ์
๊ทน๋ํ
MVC ํจํด์ ํ์คํ๋ ์ฝ๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ถ๊ณ ์์ด์, ์ฌ๋ฌ ๋ช
์ ๊ฐ๋ฐ์๋ค์ด ํจ๊ป ์์
ํ ๋ ํจ์จ์ฑ์ด ๊ทน๋ํ๋ฉ๋๋ค. ์ฝ๋๊ฐ ์ฒด๊ณ์ ์ผ๋ก ๊ด๋ฆฌ๋๊ธฐ ๋๋ฌธ์ ์ ์ง๋ณด์๊ฐ ์ฉ์ดํ๋ฉฐ, ํ๋ก์ ํธ๊ฐ ์ค๋๋๊ฑฐ๋ ๋ด๋น์๊ฐ ๋ฐ๋์ด๋ ๋ค๋ฅธ ๊ฐ๋ฐ์๊ฐ ์ฝ๊ฒ ์ด์ด๋ฐ์ ์์
ํ ์ ์์ต๋๋ค. ํ์
์ ํ์ ์กฐ๊ฑด์ธ ์ ์ง๋ณด์์ฑ์ด ๋งค์ฐ ๋ฐ์ด๋ ๊ตฌ์กฐ์
๋๋ค.
์ด๊ธฐ ๊ฐ๋ฐ์ ๋ณต์ก์ฑ๊ณผ ์๋ ์ ํ
MVC ํจํด์ ๊ตฌ์กฐ๊ฐ ๋ณต์กํ๊ธฐ ๋๋ฌธ์ ์ฒ์ ์ค๊ณํ๊ณ ์ ์ฉํ๋ ๋ฐ ์๊ฐ์ด ๋ง์ด ์์๋ ์ ์์ต๋๋ค. ์์ ํ๋ก์ ํธ์์๋ ์คํ๋ ค ๋นํจ์จ์ ์ผ ์ ์์ผ๋ฉฐ, ์ฒ์์๋ ๊ฐ๋ฐ ์๋๊ฐ ๋๋ ค์ง ์ ์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ ํ์ฅํ๊ฑฐ๋ ๋ณต์กํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ ๋น๋ก์ ๊ทธ ์ง๊ฐ๊ฐ ๋ฐํ๋์ฃ .
์ด๋ณด ๊ฐ๋ฐ์์๊ฒ ์ด๋ ค์ด ๊ฐ๋
MVC ํจํด์ ์ด๋ณด ๊ฐ๋ฐ์๋ค์๊ฒ๋ ์์ํ๊ณ ๋ณต์กํ ์ ์์ต๋๋ค. ๊ฐ ๊ตฌ์ฑ ์์์ ์ญํ ์ ์ดํดํ๊ณ ์ด๋ฅผ ์ฝ๋๋ก ๊ตฌํํ๋ ๊ณผ์ ์์ ํผ๋์ ๊ฒช๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ํนํ, ๋ชจ๋ธ, ๋ทฐ, ์ปจํธ๋กค๋ฌ๊ฐ ์ด๋ป๊ฒ ์ํธ์์ฉํ๋์ง ์ดํดํ๋ ๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ฉฐ, ์ต์ํด์ง๊ธฐ๊น์ง์ ๋ฌ๋ ์ปค๋ธ๊ฐ ์กด์ฌํฉ๋๋ค.
์๋ธ๋ฆฟ(Servlet)๊ณผ JSP(Jakarta Server Pages)๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์์ ๋ผ๋ ค์ผ ๋ ์ ์๋ ์ค์ํ ์ญํ ์ ๋งก๊ณ ์์ต๋๋ค. ์ด ๋์ด ์ด๋ป๊ฒ ์ฌ์ฉ์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ ์๋ต์ ๋ฐํํ๋์ง, ๊ทธ ๊ณผ์ ์ ํ๋์ฉ ๋ฏ์ด๋ณด๊ฒ ์ต๋๋ค.
Spring MVC๋ ๋จ์ํ ํ๋ ์์ํฌ๊ฐ ์๋๋๋ค. ์์กด์ฑ ์ฃผ์ (DI)์ด๋ AOP์ ๊ฐ์ ํต์ฌ ๊ธฐ๋ฅ์ ๋์ด, ๋ณต์กํ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋จํ๊ณ ํจ์จ์ ์ผ๋ก ๋ง๋ค ์ ์๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ๊ทธ๋ผ, Spring MVC์ ํน์ง๊ณผ ๊ตฌ์กฐ์ ์ด์ ์ ํ๋์ฉ ์ดํด๋ณด๊ฒ ์ต๋๋ค!
Model 2 Architecture
Spring MVC๋ Model, View, Controller๋ฅผ ์๋ฒฝํ๊ฒ ๋๋์ด ๊ด๋ฆฌํ ์ ์๋ Model 2 Architecture๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํฉ๋๋ค. ์ด๋ฌํ ๊ตฌ์กฐ์ ๋ถ๋ฆฌ๋ ์ ์ง๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ์ ๊ทน๋ํํ๋ฉฐ, ๊ฐ ๋ถ๋ถ์ ๋
๋ฆฝ์ ์ผ๋ก ์์ ํ ์ ์๋ ์ ์ฐ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
Front Controller ํจํด, DispatcherServlet์ ํ
Front Controller ํจํด์ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ๋ชจ๋ ์์ฒญ์ ๋จ์ผ ์ง์
์ (DispatcherServlet)์์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์
๋๋ค. Spring MVC๋ ์ด ํจํด์ ์ฑํํ์ฌ ๋ชจ๋ ์์ฒญ์ ํ ๊ณณ์์ ๊ด๋ฆฌํ๊ณ , ๊ฐ ์์ฒญ์ ์ ํฉํ Controller๋ก ๋ผ์ฐํ
ํฉ๋๋ค.
์ด๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์
์ ํ๋ฆ์ ํจ์จ์ ์ผ๋ก ์ ์ดํ๊ณ , ์ ์ง๋ณด์๊ฐ ์ฉ์ดํ ์ค์ ์ง์คํ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ํจํด ๋๋ถ์ ์ ํ๋ฆฌ์ผ์ด์
์ ํ์ฅ์ฑ๊ณผ ๊ด๋ฆฌ ์ฉ์ด์ฑ์ด ๋ํญ ํฅ์๋ฉ๋๋ค.
ํธ๋์ญ์
์ฒ๋ฆฌ์ ์๋ํ์ ์ฌ์ด ๊ด๋ฆฌ
Spring MVC๋ Spring ํ๋ ์์ํฌ์ ์ผ๋ถ์ด๊ธฐ ๋๋ฌธ์, Spring์ด ์ ๊ณตํ๋ ํธ๋์ญ์
๊ด๋ฆฌ ๊ธฐ๋ฅ์ ์์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํธ๋์ญ์
์ฒ๋ฆฌ๋ฅผ ์๋์ผ๋ก ๊ด๋ฆฌํ์ฌ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์ ์งํ ์ ์์ต๋๋ค.
DI(Dependency Injection)๋ก ์์กด์ฑ ๋ฌธ์ ํด๊ฒฐ
์์กด์ฑ ์ฃผ์
(DI)์ ํตํด ๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ์ Spring์ด ์๋์ผ๋ก ํด๊ฒฐํด์ค๋๋ค. ๊ฐ๋ฐ์๋ ๋ณต์กํ ์์กด์ฑ ๊ด๋ฆฌ์ ์ ๊ฒฝ ์ฐ์ง ์๊ณ , ๋น์ฆ๋์ค ๋ก์ง ๊ตฌํ์ ์ง์คํ ์ ์๊ฒ ๋ฉ๋๋ค.
AOP๋ก ๊ณตํต ๊ด์ฌ์ฌ๋ฅผ ์ฝ๊ฒ ์ฒ๋ฆฌ
AOP(Aspect-Oriented Programming)๋ฅผ ํ์ฉํ๋ฉด, ๋ก๊น
, ํธ๋์ญ์
๊ด๋ฆฌ, ๋ณด์ ๋ฑ์ ๊ณตํต ๊ด์ฌ์ฌ๋ฅผ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๋น์ฆ๋์ค ๋ก์ง์ ๋ฐฉํด๋ฐ์ง ์๊ณ , ๊ฐ๋ฐ์๋ ํต์ฌ ๋ก์ง์๋ง ์ง์คํ ์ ์์ต๋๋ค.
Spring MVC๋ ๋ค์ํ ์ปดํฌ๋ํธ๋ค์ด ํ๋ ฅํ์ฌ ์น ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉ์์๊ฒ ๋ฐํํ๋ ๊ฐ๋ ฅํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์ด๋ฒ์๋ Spring MVC์ ํ๋ฆ์ ์ด๋ฃจ๋ ์ค์ํ ์ปดํฌ๋ํธ๋ค์ ํ๋์ฉ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ญํ
DispatcherServlet์ Spring MVC์์ ๋ชจ๋ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๊ฐ์ฅ ๋จผ์ ๋ฐ๋ Front Controller์
๋๋ค. ์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ์์ ๋ณด๋ด๋ ๋ชจ๋ ์์ฒญ์ ์ด๊ณณ์ ๊ฑฐ์ณ์ ์ฒ๋ฆฌ๋ฉ๋๋ค.
๊ธฐ๋ฅ
Front Controller ํจํด์ ํต์ฌ
DispatcherServlet์ Spring MVC์ ์ค์ ์ง์
์ ์ผ๋ก, ์ฌ๋ฌ Controller๋ก์ ์์ฒญ์ ํจ์จ์ ์ผ๋ก ๋ถ๋ฐฐํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
์ ํ๋ฆ์ ์ผ์ํํฉ๋๋ค.
์ญํ
HandlerMapping์ ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ URL์ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ค Controller๊ฐ ์ด ์์ฒญ์ ์ฒ๋ฆฌํ ์ง ๊ฒฐ์ ํ๋ ์ค์ํ ์ญํ ์ ๋งก์ต๋๋ค.
๊ธฐ๋ฅ
์ญํ
Controller๋ ์ค์ ๋ก ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ํต์ฌ ์ญํ ์ ํฉ๋๋ค. ์์ฒญ์ ๋ง๋ ๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ์ญํ ์ ๋ด๋นํฉ๋๋ค.
๊ธฐ๋ฅ
์ญํ
ModelAndView๋ Controller๊ฐ ์ฒ๋ฆฌํ ๋ฐ์ดํฐ๋ฅผ ๋ทฐ์ ์ ๋ฌํ ๋ ์ฌ์ฉํ๋ ๊ฐ์ฒด๋ก, Model(๋ฐ์ดํฐ)๊ณผ View(ํ๋ฉด ์ ๋ณด)๋ฅผ ํจ๊ป ๋ด๊ณ ์์ต๋๋ค.
๊ธฐ๋ฅ
์ญํ
ViewResolver๋ Controller๊ฐ ๋ฐํํ ๋ทฐ ์ด๋ฆ์ ๊ธฐ๋ฐ์ผ๋ก ์ค์ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค ๋ทฐ ํ์ผ์ ์ฐพ์์ฃผ๋ ์ญํ ์ ํฉ๋๋ค.
๊ธฐ๋ฅ
viewName์ผ๋ก "home"์ ๋ฐํํ๋ฉด, ViewResolver๋ "home.jsp" ํ์ผ์ ์ฐพ์ ์ฌ์ฉ์๊ฐ ๋ณผ ์ ์๋๋ก ์ค๋นํฉ๋๋ค.์ญํ
View๋ Controller๊ฐ ์ฒ๋ฆฌํ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์๊ฒ ์๋ตํ HTML ํ์ด์ง๋ฅผ ์์ฑํ๋ ์ต์ข
๋จ๊ณ์
๋๋ค.
๊ธฐ๋ฅ
Spring MVC์์ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ด ์ด๋ป๊ฒ ์ฒ๋ฆฌ๋๊ณ , ๊ทธ ๊ฒฐ๊ณผ๊ฐ ๋ค์ ์ฌ์ฉ์์๊ฒ ์๋ต์ผ๋ก ๋ฐํ๋๋์ง ๋จ๊ณ๋ณ๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ด ํ๋ฆ์ ์ ๋๋ก ์ดํดํ๋ฉด Spring MVC์ ๋์ ์๋ฆฌ๋ฅผ ๋ช ํํ ํ์ ํ ์ ์์ต๋๋ค!
Spring MVC์ ๊ฐ๋ ฅํ ์ฒ๋ฆฌ ํ๋ฆ์ ์ดํดํ๋ฉด, ํด๋ผ์ด์ธํธ ์์ฒญ์ด ์ด๋ป๊ฒ ์ฒ๋ฆฌ๋๊ณ ์ต์ข ์ ์ผ๋ก ์ฌ์ฉ์์๊ฒ ์ ๋ฌ๋๋์ง ๋ช ํํ๊ฒ ํ์ ํ ์ ์์ต๋๋ค. ์ด ํ๋ฆ์ ๋จ๊ณ๋ณ๋ก ์์ธํ ์ค๋ช ํด ๋๋ฆฌ๊ฒ ์ต๋๋ค.
Spring MVC๋ฅผ ์ฌ์ฉํ ์น ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์ ๊ฐ ๋จ๊ณ๊ฐ ๋ช ํํ๊ฒ ๋๋์ด ์์ต๋๋ค. ์ด ๊ฐ์ด๋๋ ํ๋ก์ ํธ ์ค์ ๋ถํฐ ์์ฒญ ์ฒ๋ฆฌ, ๊ฒฐ๊ณผ ์๋ต๊น์ง์ ๋ชจ๋ ํ๋ฆ์ ์ ๋ฆฌํฉ๋๋ค. Spring MVC์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์ต๋ํ ํ์ฉํ๊ธฐ ์ํ ๊ตฌํ ๋จ๊ณ๋ฅผ ํจ๊ป ์ดํด๋ณด์ธ์!
Spring MVC ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ฑํ ๋ ํ์ํ ์ฌ๋ฌ ํต์ฌ ํ์ผ๊ณผ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ดํดํ๋ฉด, ๋ณด๋ค ์ฝ๊ฒ ํ๋ก์ ํธ๋ฅผ ์ค๊ณํ๊ณ ๊ฐ๋ฐํ ์ ์์ต๋๋ค. ์ด๋ฒ ๊ฐ์ด๋๋ Spring MVC ํ๋ก์ ํธ์ ๊ธฐ๋ณธ ๊ตฌ์ฑ ์์๋ฅผ ํ๋์ฉ ์ดํด๋ณด๋ฉฐ, ์ด๋ฅผ ์ด๋ป๊ฒ ํ์ฉํ๋์ง ์ค๋ช ํฉ๋๋ค.
ํ๋ก์ ํธ์์ Controller, Service, Model ๋ฑ ์ฃผ์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ด๊ณ ์๋ ํด๋์ค ํ์ผ๋ค์ด ์ฌ๊ธฐ์ ํฌํจ๋ฉ๋๋ค.
Controller๋ ํด๋ผ์ด์ธํธ ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ , Service๋ ๋น์ฆ๋์ค ๋ก์ง์ ๋ด๋นํ๋ฉฐ, Model์ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
์์:
src/main/java/com/example/controller/HelloController.java
HelloController๋ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ฐ์ ์ฒ๋ฆฌํ๋ Controller๋ก, /hello ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์๋ฒ ์คํ ์ ํ์ํ log4j.xml๊ณผ ๊ฐ์ ๋ก๊ทธ ์ค์ ํ์ผ์ด๋, ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ ์ค์ ํ์ผ๋ค์ด ์์นํฉ๋๋ค.
์ด๋ฌํ ์ค์ ํ์ผ๋ค์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ก๊ทธ ๊ด๋ฆฌ, ํ๊ฒฝ ์ค์ ์ ์ ์ํ๋ ๋ฐ ํ์์ ์ ๋๋ค.
์์:
log4j.xml
์ ํ๋ฆฌ์ผ์ด์
์ ๋ก๊ทธ ์ค์ ํ์ผ๋ก, ๋ก๊ทธ ๋ ๋ฒจ, ํ์ผ ๊ฒฝ๋ก ๋ฑ์ ๊ด๋ฆฌํฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ๊ธฐ๋ฅ์ ๊ฒ์ฆํ๋ ํ ์คํธ ์ฝ๋๋ฅผ ํฌํจํ๋ ๋๋ ํฐ๋ฆฌ์ ๋๋ค.
JUnit์ด๋ Spring Test ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ ํ ์คํธ ๋ฐ ํตํฉ ํ ์คํธ๋ฅผ ์์ฑํฉ๋๋ค.
์์:
src/test/java/com/example/controller/HelloControllerTest.java
HelloController๊ฐ ์์๋๋ก ์๋ํ๋์ง ํ์ธํ๋ ํ
์คํธ ์ฝ๋๊ฐ ์ฌ๊ธฐ์ ์์ฑ๋ฉ๋๋ค.
Spring ํ๋ ์์ํฌ๋ฅผ ์ ๋๋ก ๋์ํ๊ฒ ํ๊ธฐ ์ํ ์ค์ ํ์ผ๋ค์ ๋๋ค.
์ฃผ๋ก XML ํ์ผ ๋๋ Java Config ํ์ผ์ ์ฌ์ฉํด ๋น(bean) ์ค์ , DispatcherServlet ์ค์ ๋ฑ์ ์ ์ํฉ๋๋ค.
์์:
servlet-context.xml
Spring MVC์ ์ค์ ํ์ผ๋ก, DispatcherServlet ์ค์ , Controller ๋งคํ, View Resolver ์ค์ ๋ฑ์ ํฌํจํฉ๋๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ๋ณผ ๋์ ์น ํ์ด์ง๋ฅผ ๊ตฌ์ฑํ๋ JSP ํ์ผ๋ค์ด ์์นํฉ๋๋ค.
JSP๋ Controller๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ํ๋ฉด์ ๋์ ์ผ๋ก ํ์ํฉ๋๋ค.
์์:
src/main/webapp/WEB-INF/views/hello.jsp
hello.jsp๋ HelloController๊ฐ ์ฒ๋ฆฌํ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ํ๋ฉด์ ๋ณด์ฌ์ค HTML ํ์ด์ง๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
web.xml๊ณผ ๊ฐ์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค์ ํ์ผ๋ค์ด ํฌํจ๋ฉ๋๋ค.
DispatcherServlet์ ์ค์ ํ๊ฑฐ๋, ์๋ธ๋ฆฟ ํํฐ, ๋ฆฌ์ค๋ ๋ฑ์ ์ ์ํ์ฌ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋์์ ์ค์ ํฉ๋๋ค.
์์:
web.xml
DispatcherServlet์ ๋ฑ๋กํ๊ณ , URL ๋งคํ์ ์ค์ ํ๋ ํ์ผ์
๋๋ค. Spring MVC์ ์ค์ํ ์์์ ์ญํ ์ ํฉ๋๋ค.
ํ๋ก์ ํธ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์กด์ฑ๊ณผ ๋น๋ ์ค์ ์ ๊ด๋ฆฌํ๋ pom.xml ํ์ผ์ด ์ฌ๊ธฐ์ ์์นํฉ๋๋ค.
pom.xml์ ํตํด Spring, JUnit, MySQL Connector ๋ฑ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ ์ํ๊ณ , Maven์ด ์๋์ผ๋ก ์์กด์ฑ์ ๊ด๋ฆฌํฉ๋๋ค.
์์:
pom.xml
Maven ์ค์ ํ์ผ๋ก, ํ๋ก์ ํธ์์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋น๋ ํ๋ฌ๊ทธ์ธ๋ค์ ์ ์ํ์ฌ ๊ด๋ฆฌํฉ๋๋ค.
src/main/java/com/example/controller/HomeController.java:
Controller ํด๋์ค๋ /home ๊ฒฝ๋ก๋ก ๋ค์ด์จ ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ /home์ ์ ์ํ๋ฉด ์ด ํด๋์ค๊ฐ ์์ฒญ์ ๋ฐ์ Model์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ณ , View์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
src/main/webapp/WEB-INF/views/home.jsp:
home.jsp๋ HomeController๊ฐ ์ฒ๋ฆฌํ ๋ฐ์ดํฐ๋ฅผ ๋ฐํ์ผ๋ก ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค HTML ํ์ด์ง๋ฅผ ๋์ ์ผ๋ก ์์ฑํฉ๋๋ค.
src/main/resources/application.properties:
Spring ์ค์ ํ์ผ๋ก, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ ๋ณด, ๋ก๊ทธ ์ค์ , ๊ธฐํ ํ๊ฒฝ ์ค์ ๋ค์ด ํฌํจ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ ๋ณด๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
pom.xml:
Maven ์ค์ ํ์ผ๋ก, ํ๋ก์ ํธ์์ ์ฌ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Sprint MVC, JUnit, MySQL ๋ฑ)๋ฅผ ์ ์ํ๊ณ ๋น๋ ํ๋ฌ๊ทธ์ธ ๋ฑ์ ์ค์ ํฉ๋๋ค.
src/test/java/com/example/controller/HomeControllerTest.java:
JUnit ํ
์คํธ ํ์ผ๋ก, HomeController๊ฐ ์์๋๋ก ๋์ํ๋์ง ํ
์คํธํ๋ ์ฝ๋๊ฐ ์์ฑ๋ฉ๋๋ค.
ApplicationContext๋ Spring ํ๋ ์์ํฌ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํต์ฌ ์ปดํฌ๋ํธ๋ก, Inversion of Control (IoC) ์์น์ ๊ตฌํํ๋ ์ฃผ์ ์ปจํ ์ด๋์ ๋๋ค. ์ด ์ปจํ ์ด๋๋ ๋น(bean)์ ๊ด๋ฆฌํ๊ณ , ์์กด์ฑ ์ฃผ์ (DI)์ ํตํด ๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ์ ์๋์ผ๋ก ์ฐ๊ฒฐํด ์ค๋๋ค.
๋น(bean) ๊ด๋ฆฌ ๐ฏ
์์กด์ฑ ์ฃผ์ (DI) ๐
๋น ์ค์ ๋ฐ ์กฐํ ๐
๋ค์์ Spring ApplicationContext์์ ๋น ๊ด๋ฆฌ์ ์์กด์ฑ ์ฃผ์ ์ด ์ด๋ป๊ฒ ๋์ํ๋์ง ๋ณด์ฌ์ฃผ๋ ๊ฐ๋จํ ์์์ ๋๋ค.
// Service ์ธํฐํ์ด์ค
public interface UserService {
void createUser();
}
// Service ๊ตฌํ์ฒด
public class UserServiceImpl implements UserService {
@Override
public void createUser() {
System.out.println("Creating a user...");
}
}
// Controller
public class UserController {
private UserService userService;
// ์์ฑ์ ์ฃผ์
(DI)
public UserController(UserService userService) {
this.userService = userService;
}
public void handleRequest() {
userService.createUser();
}
}
<beans>
<!-- UserService ๋น ์ ์ -->
<bean id="userService" class="com.example.UserServiceImpl" />
<!-- UserController ๋น ์ ์ ๋ฐ ์์กด์ฑ ์ฃผ์
-->
<bean id="userController" class="com.example.UserController">
<constructor-arg ref="userService" />
</bean>
</beans>
userService ๋น์ ๋จผ์ ์์ฑํฉ๋๋ค.userController ๋น์ ์์ฑํ๊ณ , ๊ทธ ์์ฑ์์ userService ๋น์ ์ฃผ์
ํ์ฌ ์์กด์ฑ์ ํด๊ฒฐํฉ๋๋ค.Spring ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ฒฝํ๊ฒ ์ดํดํ๋ ค๋ฉด ContextLoaderListener์ Root ApplicationContext์ ์ญํ ์ ์์์ผ ํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ์ญ์์ ์ค์ํ ๋น์ ๊ด๋ฆฌํ๊ณ ์ค์ ํ๋ ๋ฐฉ๋ฒ, ์ง๊ธ๋ถํฐ ์์๋ณผ๊น์?
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
contextConfigLocation์ ์ง์ ํ๊ณ , param-value๋ก root-context.xml ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํฉ๋๋ค./WEB-INF/spring/root-context.xml์ ๊ณตํต์ผ๋ก ์ฌ์ฉ๋๋ ์ต์์ ApplicationContext ์ค์ ํ์ผ์ ๊ฒฝ๋ก์
๋๋ค. ์ด ํ์ผ์ ๋น ์ค์ , ๋ฐ์ดํฐ ์์ค ์ค์ , ํธ๋์ญ์
๊ด๋ฆฌ์ ๊ฐ์ ๊ณตํต์ ์ธ ์ค์ ์ด ํฌํจ๋ ์ ์์ต๋๋ค.<!-- root-context.xml ์์ -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ค์ -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<!-- ํธ๋์ญ์
๊ด๋ฆฌ ์ค์ -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
root-context.xml ํ์ผ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ค์ ๊ณผ ํธ๋์ญ์
๊ด๋ฆฌ ์ค์ ์ด ํฌํจ๋์ด ์์ต๋๋ค. ์ด ์ค์ ์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.์ ํ๋ฆฌ์ผ์ด์ ์์ ๐ฌ
Root ApplicationContext ์ด๊ธฐํ โ๏ธ
/WEB-INF/spring/root-context.xml)๋ฅผ ์ฐพ์ Spring ApplicationContext๋ฅผ ์ด๊ธฐํํฉ๋๋ค.๋น(bean) ๊ด๋ฆฌ ๐๏ธ
DispatcherServlet์ Spring MVC ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ชจ๋ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ค์์์ ์ฒ๋ฆฌํ๊ณ , ์ ์ ํ ์ปจํธ๋กค๋ฌ๋ก ์ ๋ฌํ๋ Front Controller์ ๋๋ค. DispatcherServlet์ ์ค์ ์ web.xml ํ์ผ์ ํตํด ์ด๋ฃจ์ด์ง๋ฉฐ, ์ฌ๊ธฐ์ DispatcherServlet์ด ์ด๋ป๊ฒ ์ค์ ๋๊ณ ๋์ํ๋์ง ์๋ฒฝํ๊ฒ ์ดํดํด์ผ ํฉ๋๋ค!
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/app-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
/WEB-INF/spring/app-config.xml ๊ฒฝ๋ก์์ Spring ์ปจํ
์คํธ๋ฅผ ์ด๊ธฐํํฉ๋๋ค.Spring MVC๋ Java ๊ธฐ๋ฐ ์น ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์์ ๋งค์ฐ ์ค์ํ ํ๋ ์์ํฌ์ ๋๋ค. ์ด๋ฒ ๊ธ์์๋ Spring MVC ํ๋ก์ ํธ์ ๊ธฐ๋ณธ ์ค์ ๋ถํฐ ๋์ ๊ณผ์ ๊น์ง๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. DispatcherServlet๋ถํฐ Controller, ViewResolver, ๊ทธ๋ฆฌ๊ณ JSP๊น์ง, ํ๋ก์ ํธ์ ์ ๋ฐ์ ์ธ ํ๋ฆ์ ์ดํดํ ์ ์์ต๋๋ค.
DispatcherServlet์ Spring MVC์ ํต์ฌ์ธ Front Controller๋ก, ๋ชจ๋ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ฐ์ ์ฒ๋ฆฌํฉ๋๋ค. ๋จผ์ web.xml ํ์ผ์์ ์ด ์๋ธ๋ฆฟ์ ์ค์ ํฉ๋๋ค.
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- DispatcherServlet ์ค์ -->
<servlet>
<servlet-name>mainServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/main-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- DispatcherServlet URL ๋งคํ -->
<servlet-mapping>
<servlet-name>mainServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
์ด์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ Controller๋ฅผ ์์ฑํด๋ด ์๋ค. ์๋ ์ฝ๋๋ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ , Model ๋ฐ์ดํฐ๋ฅผ ๋ทฐ๋ก ์ ๋ฌํ๋ HelloController์ ๋๋ค.
package com.example.hello;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
@GetMapping("/")
public String index(Model model) {
// Model์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐ
model.addAttribute("name", "ํ๊ธธ๋");
// "index"๋ View ์ด๋ฆ์ด๋ฉฐ, ViewResolver์ ์ํด /WEB-INF/views/index.jsp๋ก ๋งคํ๋ฉ๋๋ค.
return "index";
}
}
ViewResolver๋ ๋ ผ๋ฆฌ์ ์ธ ๋ทฐ ์ด๋ฆ์ ์ค์ JSP ํ์ผ๋ก ๋งคํํด์ฃผ๋ ์ญํ ์ ํฉ๋๋ค. Spring MVC์์ ์ด ์ค์ ์ servlet-context.xml ํ์ผ์์ ์ ์๋ฉ๋๋ค.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- Controller ์๋ ์ค์บ -->
<context:component-scan base-package="com.example.hello" />
<!-- ViewResolver ์ค์ -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
๋ง์ง๋ง์ผ๋ก, ์ค์ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ง index.jsp ํ์ผ์ ์์ฑํฉ๋๋ค. ํด๋ผ์ด์ธํธ์๊ฒ ์๋ต์ผ๋ก ๋ณด์ฌ์ง HTML ํ์ด์ง์ ๋๋ค.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello Spring MVC</title>
</head>
<body>
<h3>์๋
ํ์ธ์, Spring MVC ํ๋ก์ ํธ์
๋๋ค!</h3>
<h1>ํ์ํฉ๋๋ค, ${name}๋!</h1>
</body>
</html>
์ต๊ทผ์๋ XML ์ค์ ๋์ ์๋ฐ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ JavaConfig ๋ฐฉ์์ด ๊ถ์ฅ๋ฉ๋๋ค. ์๋๋ JavaConfig ๋ฐฉ์์ผ๋ก ์ค์ ํ ์์์ ๋๋ค.
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.hello")
public class WebConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
Spring MVC๋ฅผ ์ฌ์ฉํ๋ค ๋ณด๋ฉด DispatcherServlet, root-context.xml, ๊ทธ๋ฆฌ๊ณ [์ด๋ฆ]-servlet.xml์ ๋ํด ํผ๋์ค๋ฌ์ธ ๋๊ฐ ๋ง์ต๋๋ค. ์ด ๊ธ์์๋ ์ด ์ธ ๊ฐ์ง ์์์ ์ญํ ๊ณผ ์ํธ ๊ด๊ณ๋ฅผ ๋ช
ํํ๊ฒ ์ ๋ฆฌํ๊ณ , ์ root-context.xml์ ๋ณ๋๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์์ง ์์ธํ ์์๋ณด๊ฒ ์ต๋๋ค.
<context:component-scan base-package="com.example.controller" /><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean><mvc:annotation-driven /><mvc:resources mapping="/resources/**" location="/static/" /><bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean><bean id="userService" class="com.example.service.UserServiceImpl" />web.xml์์ ContextLoaderListener๋ฅผ ์ค์ ํ์ฌ root-context.xml์ ๋ก๋ํฉ๋๋ค.
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
ContextLoaderListener๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ Root ApplicationContext๋ฅผ ์ด๊ธฐํํ๊ณ , ์ง์ ๋ ์์น์ ์ค์ ํ์ผ์ ๋ก๋ํฉ๋๋ค.
@Configuration, @ComponentScan, @Bean ๋ฑ์ ํ์ฉํ์ฌ ์ค์ ํ์ผ์ ๊ตฌ์ฑํฉ๋๋ค.root-context.xml์ ๋ณ๋๋ก ์ฌ์ฉํ๋ ์ด์ ๋?๐คSpring MVC๋ฅผ ์ฌ์ฉํ๋ค ๋ณด๋ฉด web.xml์์ ๋ชจ๋ ์ค์ ์ ์ฒ๋ฆฌํ ์ ์์์๋ ๋ถ๊ตฌํ๊ณ , root-context.xml์ ๋ณ๋๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ฅผ ์์ฃผ ์ ํ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ ์ด๋ ๊ฒ ๋ณ๋์ ์ค์ ํ์ผ์ ์ฌ์ฉํ๋ ๊ฑธ๊น์? ์ด๋ฒ ๊ธ์์๋ ๊ทธ ์ด์ ์ ํจ๊ป ํ๋ก์ ํธ ๊ตฌ์กฐํ์ ์ ์ง๋ณด์์ฑ ์ธก๋ฉด์์์ ์ด์ ์ ์์ธํ ์์๋ณด๊ฒ ์ต๋๋ค. ๐ง
web.xml์์ ๋ชจ๋ ์ค์ ์ ํ ์ ์๋๊ฐ?๋ค, ๊ธฐ์ ์ ์ผ๋ก๋ ๊ฐ๋ฅํฉ๋๋ค! ๐ web.xml์์ ContextLoaderListener๋ DispatcherServlet์ ์ด๊ธฐํ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์ค์ ์ ์ง์ ํ ์ ์์ต๋๋ค. ์ฆ, root-context.xml ์์ด๋ Spring ์ ํ๋ฆฌ์ผ์ด์
์ ๋์์ํฌ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, context-param์์ ์ง์ ๋น ์ค์ ์ ์ ์ํ ์ ์์ต๋๋ค.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/app-servlet.xml</param-value>
</context-param>
ํ์ง๋ง ๋ชจ๋ ์ค์ ์ web.xml์ ๋ชฐ์๋ฃ๋ ๊ฒ์ ์ฌ๋ฌ ๊ฐ์ง ๋ฌธ์ ๋ฅผ ์ผ๊ธฐํ ์ ์์ต๋๋ค. โ ๏ธ
root-context.xml์ ์ฌ์ฉํ๋ ์ด์ root-context.xml์ ๋ณ๋๋ก ๋๋ ๊ฒ์ ํ๋ก์ ํธ์ ๊ตฌ์กฐํ์ ์ ์ง๋ณด์์ฑ์ ๋์ด๊ธฐ ์ํจ์
๋๋ค. ํนํ, ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ง์๋ก ์ค์ ์ ๋๋์ด ๊ด๋ฆฌํ๋ ๊ฒ์ด ํจ์ฌ ์ ๋ฆฌํฉ๋๋ค. ๊ทธ ์ด์ ๋ฅผ ํ๋์ฉ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๐
์ ์ญ ์ค์ vs ์๋ธ๋ฆฟ๋ณ ์ค์
root-context.xml: ์ ํ๋ฆฌ์ผ์ด์
์ ์ฒด์์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋๋ ๋น(์: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ, ์๋น์ค ๊ณ์ธต)์ ์ค์ ํฉ๋๋ค.[์ด๋ฆ]-servlet.xml: ์๋ธ๋ฆฟ๋ณ๋ก ๊ตฌ์ฒด์ ์ธ ์ค์ (MVC ๊ตฌ์ฑ ์์, ์ปจํธ๋กค๋ฌ, ๋ทฐ ๋ฆฌ์กธ๋ฒ ๋ฑ)์ ์ ์ํฉ๋๋ค.์ด์ : ์ญํ ์ ๋ช ํํ๊ฒ ๋ถ๋ฆฌํ๋ฉด, ์ ์ญ ์ค์ ๋ณ๊ฒฝ ์ ๊ฐ ์๋ธ๋ฆฟ๋ณ ์ค์ ํ์ผ์ ์์ ํ ํ์๊ฐ ์์ต๋๋ค. ๐
์ ํ๋ฆฌ์ผ์ด์ ๊ท๋ชจ ํ๋ ์ ์ ๋ฆฌ
root-context.xml์, ์๋ธ๋ฆฟ๋ณ ์ค์ ์ ๊ฐ [์ด๋ฆ]-servlet.xml์ ๋๋ฉด ์ค๋ณต๋ ์ค์ ์์ด ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค.์์
root-context.xml์, ๊ฐ๋ณ ์ค์ ์ ๊ฐ ์๋ธ๋ฆฟ ์ค์ ํ์ผ์ ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํฉ๋๋ค.์ ์ง๋ณด์์ ์ฉ์ด์ฑ
web.xml ํ๋์ ๋ชฐ์๋ฃ์ผ๋ฉด ํ๋ก์ ํธ๊ฐ ์ปค์ง์๋ก ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ง๋๋ค. ๐ตํ์ ์ ์ด์
๋ ๋ฆฝ์ ์ธ ์๋ธ๋ฆฟ ์ปจํ ์คํธ
root-context.xml์ ํตํด ์์ฑ๋ Root ApplicationContext๋ ๋ชจ๋ ์๋ธ๋ฆฟ์์ ๊ณตํต์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.์ด์