- POJO๋ ๋ฌด์์ธ๊ฐ์? Spring Framework์์ POJO๋ ๋ฌด์์ด ๋ ์ ์์๊น์?
- Spring DI/IoC๋ ์ด๋ป๊ฒ ๋์ํ๋์?
- IoC ์ปจํ ์ด๋์ ์ญํ ์ ๋ฌด์์ด ์์๊น์?
- Spring IoC/DI(์์กด์ฑ ์ฃผ์
)์ ๋ฐฉ๋ฒ์ ๋ํด ์๋๋๋ก ์ค๋ช
ํด์ฃผ์ธ์.
- ๊ฐ DI ์ฃผ์ ๋ฐฉ์์ ์ฐจ์ด์ ๊ณผ ์ด์ ์ ๋ํด์ ์ค๋ช ํด์ฃผ์ธ์.
- ์์กด์ฑ๊ณผ ์ค์ ๊ฐ์ ์์ฑ์ ์ธ์๋ก ์ฃผ์ ํด์ผ ํ๋ ์ด์ ์ ๋ํด ์ค๋ช ํด์ฃผ์ธ์.
- MVC ํจํด์ด๋?
- ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ด๋ ๋ฌด์์ธ๊ฐ์?
- Spring Web MVC์ Dispatcher Servlet์ ๋์ ์๋ฆฌ์ ๋ํด์ ๊ฐ๋จํ ์ค๋ช ํด์ฃผ์ธ์.
- AOP(Aspect Oriented Programming)๋ ๋ฌด์์ผ๊น์?
- Spring์์ CORS ์๋ฌ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ ์ค๋ช ํด์ฃผ์ธ์.
- Bean์ ๋ํด ์ค๋ช
ํด๋ณด์ธ์.
- Spring Bean์ด๋ ๋ฌด์์ธ๊ฐ์?
- ์คํ๋ง Bean์ ์์ฑ ๊ณผ์ ์ ์ค๋ช ํด์ฃผ์ธ์.
- ์คํ๋ง Bean์ Scope์ ๋ํด์ ์ค๋ช ํด์ฃผ์ธ์.
- Bean/Component ์ด๋ ธํ ์ด์ ์ ๋ํด์ ์ค๋ช ํด์ฃผ์๊ณ , ๋์ ์ฐจ์ด์ ์ ๋ํด ์ค๋ช ํด์ฃผ์ธ์.
- Getter์ Setter๋ฅผ ์ฌ์ฉํด์ผํ๋ ์ด์ ์ ๋ํด์ ์ค๋ช ํด์ฃผ์ธ์.
- Spring์์ ์์ธ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ค๋ช ํด์ฃผ์ธ์.
- Filter์ Interceptor ์ฐจ์ด
- Filter๋ Servlet์ ์คํ์ด๊ณ , Interceptor๋ Spring MVC์ ์คํ์ ๋๋ค. Spring Application์์ Filter์ Interceptor๋ฅผ ํตํด ์์ธ๋ฅผ ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
- DTO๋ฅผ ์ฌ์ฉํ๋ ์ด์
POJO๋, Plain Old Java Object์ ์ฝ์๋ก, ๋ค๋ฅธ ํด๋์ค๋ ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ง ์์, ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฅ๋ง ๊ฐ์ง ์๋ฐ ๊ฐ์ฒด๋ฅผ ๋งํฉ๋๋ค.
์ฆ, POJO๋ ๊ฐ์ฒด์งํฅ์ ์๋ฆฌ์ ์ถฉ์คํ๊ณ , ํน์ ๊ท์ฝ๊ณผ ํ๊ฒฝ์ ์ข
์๋์ง ์๊ฒ ์ฌํ์ฉ ๋ ์ ์๊ฒ ์ค๊ณ๋ ๊ฐ์ฒด๋ฅผ ๋งํฉ๋๋ค.
POJO๋ฅผ ์ฌ์ฉํ ๋์ ์ด์ ์, ์ข
์๋ ์ฝ๋๋ฅผ ๋ถ๋ฆฌํจ์ผ๋ก ์ฝ๋์ ๊ฐ๊ฒฐํด์ง๋๋ค.
๋ํ, ์๋ํ ํ
์คํธ์ ์ ๋ฆฌํ๊ณ ์ ์ง๋ณด์์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
Spring์ ๊ฐ์ฅ ๋ํ์ ์ธ POJOํ๋ ์์ํฌ์ด๋ฉฐ, POJO๋ ๊ฐ์ฒด์งํฅ์ ์ธ ์๋ฆฌ์ ์ถฉ์คํ ๋ฐฉ์์ผ๋ก ์ค๊ณ๋ ์๋ฐ ๊ฐ์ฒด์
๋๋ค.
Spring์์๋ ๋๋ฉ์ธ๊ณผ ๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๋ ๋์์ด POJO๊ฐ ๋ ์ ์์ต๋๋ค.
import javax.jms.MessageListener;
import javax.jms.Message;
import javax.jms.JMSException;
// ์ ์์ค์ ๊ธฐ์ ๊ณผ ํ๊ฒฝ์ ์ข
์์ ์ธ ๊ฐ์ฒด
public class OrderProcesser implements MessageListener {
@Override
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
OrderPlaced event = OrderPlaced.fromJson(((TextMessage) message).getText()); // ์ฃผ๋ฌธ ์ ์ ์ฒ๋ฆฌํ๊ธฐ
} catch (JMSException error) {
throw new RuntimeException("The message could not be read.", error);
}
} else {
throw new IllegalArgumentException("Message must be of type TextMessage");
}
}
}์๋ฐ ์ํฐํ๋ผ์ด์ฆ ๊ธฐ์ (= ํธ๋์ญ์
, ๋ณด์, ๋ฉ์ผ, ๋ฉ์์ง, ์บ์์ ๊ฐ์ ์ํฐํ๋ผ์ด์ฆ ์ ํ๋ฆฌ์ผ์ด์
์์ ์๊ตฌ๋๋ ๊ธฐ์ ) ์ค ํ๋์ธ
์๋ฐ ๋ฉ์ธ์ง ์๋น์ค๋ก ์์ฑ๋ ๊ฐ์ฒด๊ฐ ์์ต๋๋ค.
์ด ๊ฐ์ฒด๋ ์๋ฐ ๋ฉ์ธ์ง ์๋น์ค API๋ฅผ ์ฌ์ฉํด ๋ฉ์ธ์ง๋ฅผ ์์ ํ๊ณ
๋ฉ์ธ์ง์ ๋ด๊ธด JSON ๋ฐ์ดํฐ๋ฅผ OrderPlaced ๊ฐ์ฒด๋ก ๋ณํ ํ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฉ์ธ์ง๋ฅผ ๋ค๋ฃฐ ๋ ๋ฐ์ํ ์ ์๋ checked exception๋ ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค.
import org.springframework.jms.annotation.JmsListener;
// ์ ์์ค์ ๊ธฐ์ ๊ณผ ํ๊ฒฝ์ ์ข
์๋์ง ์๊ฒ ์ค๊ณ๋ ๊ฐ์ฒด
public class OrderProcesser {
@JmsListener(destination = "pos")
public void accept(OrderPlaced event) {
// ์ฃผ๋ฌธ ์ ์ ์ฒ๋ฆฌํ๊ธฐ
}
}์๋๋ ์คํ๋ง์ ์ด์ ๊ฐ๋ฅํ ์๋น์ค ์ถ์ํ ๊ธฐ์ ์ ์ฌ์ฉํด ์์ฑ๋ POJO ๋ฐฉ์์ ์ฝ๋์
๋๋ค.
annotation์ผ๋ก ๋ฉ์ธ์ง ์์ ์ ์ ์ธํ๊ณ method parameter๋ฅผ ํตํด ์์ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ OrderPlaced ๊ฐ์ฒด๋ก ๋ค๋ฃจ๊ฒ ๋ค๊ณ ์์ฑ ํ ๋ฐ๋ก ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํฉ๋๋ค.
์ด๋ ๋ฏ ํน์ ๊ธฐ์ ๊ณผ ํ๊ฒฝ์ ์ข
์๋์ง ์๋ ๊ฐ์ฒด๋ ๊น๋ํ ์ฝ๋๊ฐ ๋ ์ ์์ต๋๋ค.
์ฒซ๋ฒ์งธ ์ฝ๋์ ๊ฐ์ด ๊ธฐ์ ๊ณผ ํ๊ฒฝ์ ์ข
์์ ์ธ ๊ฐ์ฒด๊ฐ ๋น์ฆ๋์ค ๋ก์ง๊ณผ ํจ๊ป ์์ฌ ์์ผ๋ฉด ์ง์ ๋ถํ ์ฝ๋๊ฐ ๋ฐ์ํฉ๋๋ค.
์ฝ๊ณ ์ดํดํ๊ธฐ๋ ์ด๋ ค์ธ ๋ฟ๋๋ฌ ๊ฒ์ฆ์ด๋ ํ
์คํธ ์์ฑ์๋ ์ด๋ ค์์ด ์์ผ๋ฏ๋ก ์ ์ง ๋ณด์์ ํฐ ๋ถ๋ด์ด ๋ฉ๋๋ค.
์คํ๋ง์ ์ํฐํ๋ผ์ด์ฆ ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋ฐ์ ๋ชจ๋ ์์ญ๊ณผ ๊ณ์ธต์์ POJO ๋ฐฉ์์ ๊ตฌํ์ด ๊ฐ๋ฅํ๋๋ก ๋ง๋ค์ด์ก์ต๋๋ค.
์ด๋ฅผ ์ด์ฉํ๋ฉด POJO ํ๋ก๊ทธ๋๋ฐ์ ์ฅ์ ์ ๊ทธ๋๋ก ์ด๋ ค ์ํฐํ๋ผ์ด์ฆ ์ ํ๋ฆฌ์ผ์ด์
์ ํต์ฌ ๋ก์ง์ ๊ฐ์ฒด ์งํฅ์ ์ธ POJO ๊ธฐ๋ฐ์ผ๋ก ๊น๋ํ๊ฒ ๊ตฌํํ๊ณ
๋์์ ์ํฐํ๋ผ์ด์ฆ ํ๊ฒฝ์ ๊ฐ์ข
์๋น์ค์ ๊ธฐ์ ์ ์ธ ํ์๋ฅผ POJO ๋ฐฉ์์ผ๋ก ๋ง๋ค์ด์ง ์ฝ๋์ ์ ์ฉํ ์ ์์ต๋๋ค.
IoC(์ ์ด์ ์ญ์ )์ main() ๋ฉ์๋๊ฐ ๋ค์ ์ฌ์ฉ ๊ฐ์ฒด๋ฅผ ๊ฒฐ์ , ์์ฑ, ํธ์ถํด ๋๊ฐ๋ ์ผ๋ฐ์ ์ธ ํ๋ก๊ทธ๋จ ํ๋ฆ๊ณผ ๋ฌ๋ฆฌ ์ธ๋ถ์์ ์ ์ด ํ๋ฆ์ ๊ด๋ฆฌํ๋ ๊ฒ์
๋๋ค.
์คํ๋ง์์๋ IoC ์ปจํ
์ด๋๋ฅผ ์ ๊ณตํ์ฌ ๋ฐํ์ ์์ ์ ๊ฐ์ฒด๊ฐ์ ์์กด ๊ด๊ณ๋ฅผ ๊ฒฐ์ ํ๊ณ , ๊ฐ์ฒด ๋ ํผ๋ฐ์ค๋ ์ ๊ณตํด ์ค๋๋ค.
DI๋ ํด๋์ค ๊ฐ ์ง์ ์ ์ธ ์์กด ๊ด๊ณ ํ์ฑ์ ๋ฐ์ํ๋ ๋์ ๊ฒฐํฉ๋(coupling)๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด
interface์ ํ์ฉ์ ํตํด ์ธ๋ถ์์ ์์ฑ๋ ๊ฐ์ฒด๋ฅผ ์ฃผ์
ํ setter๋ ์์ฑ์๋ฅผ ํตํด ์ฌ์ฉํฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ์ด ์ฝ๋์ ์ฌํ์ฉ์ฑ์ ๋์ด๊ณ ์ฌ์ฉ์ ์๊ตฌ์ ๋ํด ์ ์ฐํ๊ฒ ๋์ฒํ ์ ์์ต๋๋ค.
์ปจํ
์ด๋๋ ๊ฐ์ฒด์ ์๋ช
์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ๊ณ , ์์ฑ๋ ์ธ์คํด์ค๋ค์๊ฒ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ญํ ์ ํฉ๋๋ค.
์คํ๋ง์์๋ IoC ์ปจํ
์ด๋๊ฐ ๊ฐ์ฒด์ ์์ฑ๊ณผ ์์กด์ฑ ๊ด๋ฆฌ๋ฅผ ํ๊ณ , POJO์ ์์ฑ, ์ด๊ธฐํ, ์๋น์ค, ์๋ฉธ์ ๋ํ ๊ถํ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๋ฐ๋ผ์ ๊ฐ๋ฐ์๋ ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง์ ์ง์คํ์ฌ ๊ฐ๋ฐ ํ ์ ์์ต๋๋ค.
- ์์ฑ์(Constructor Injection) ์ฃผ์
- ํ๋(Field Injection) ์ฃผ์
- ์์ ์(Setter Injection) ์ฃผ์
์์ ์ ์ฃผ์ (Setter Injection)์ Setter ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์์กด์ฑ ์ฃผ์ ์ ํ๊ธฐ ๋๋ฌธ์, ๋ฐํ์์ ์์กด๊ด๊ณ๋ฅผ ์ฃผ์ ํด ๋ฎ์ ๊ฒฐํฉ๋๋ฅผ ๊ฐ๋๋ค๋ ์ฅ์ ์ด ์์ง๋ง, Setter ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์, ์์กด์ฑ์ ์ฃผ์ ํด์ฃผ์ง ์๋ ๊ฒฝ์ฐ์๋ ๊ฐ์ฒด๊ฐ ์์ฑ๋์ด NullPointException์ด ๋ฐ์ํ๋ค๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
ํ๋ ์ฃผ์ (Field Injection)์ ๋ณ์ ์ ์ธ๋ถ์ @Autowired ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ์๋์ผ๋ก ์์กด์ฑ์ด ์ฃผ์ ๋๊ธฐ ๋๋ฌธ์ ๊ฐํธํ์ง๋ง, ์ฐธ์กฐ ๊ด๊ณ๋ฅผ ๋์ผ๋ก ํ์ธํ๊ธฐ ์ด๋ ต๊ณ ์์ ์ ์ฃผ์ ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฐํ์์ ์์กด๊ด๊ณ๋ฅผ ์ฃผ์ ํด NullPointerException์ด ๋ฐ์ํ ์ ์๋ค๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์์ฑ์ ์ฃผ์ (Constructor Injection)์ ์ ์ธ๋ ์์ฑ์๋ฅผ ์ด์ฉํด ์์กด์ฑ์ ์ฃผ์ ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ์์ ์ ์ฃผ์ ๊ณผ ํ๋ ์ฃผ์ ๊ณผ๋ ๋ค๋ฅด๊ฒ ์์กด๊ด๊ณ๋ฅผ ์ฃผ์ ํ์ง ์๋ ๊ฒฝ์ฐ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์๊ฐ ์์ต๋๋ค. ์ด๋ฌํ ํน์ง ๋๋ถ์ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ๋์์ ํด๋น ์ค๋ฅ๋ฅผ ์ก์๋ผ ์ ์์ต๋๋ค.
์์กด์ฑ๊ณผ ์ค์ ๊ฐ์ ์์ฑ์ ์ธ์๋ก ์ฃผ์ ํด์ผ ํ๋ ์ด์ ์ ๋ํด ์ค๋ช ํด์ฃผ์ธ์.
ํ๋ ์ฃผ์ ๊ณผ ์์ ์ ์ฃผ์ ์ ๊ฒฝ์ฐ ๋น์ด ์์ฑ๋ ํ์ ์ฐธ์กฐ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ฐํ์ ์๊น์ง ์ค๋ฅ๋ ๊ฒฝ๊ณ ์์ด ๊ตฌ๋๋์ง๋ง, ์์ฑ์ ์ฃผ์ ์ ๊ฒฝ์ฐ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ๋ ์์ ์ํ ์ฐธ์กฐ์ ๋ํ ์์ธ์ฒ๋ฆฌ๋ฅผ ๋ฐ์ ์ ์์ด ์๋ฒ ๊ตฌ๋์ ์์ด ํฌ๋ฆฌํฐ์ปฌํ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ ์ ์๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํฉ๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ก ์คํ๋ง ๋ ํผ๋ฐ์ค์์๋ ์์ฑ์ ์ฃผ์
์ ๊ถ์ฅํ๊ณ ์์ต๋๋ค.
Bean A โ Bean B โ Bean A ์ฒ๋ผ, ๋น๋ค์ด ์๋ก ๊ณ์ ์ฐ๊ฒฐ๋์ด ์๋ ์ํ๋ฅผ ์๋ฏธํฉ๋๋ค.
์ํ ์ฐธ์กฐ๊ฐ ๋ฐ์ํ๋ฉด ์ปจํ
์ด๋๋ ์ด๋ ๋น์ ๋จผ์ ์์ฑํด์ผํ๋์ง ํ๋จํ์ง ๋ชปํ๊ณ ์๋ฌ๋ฅผ ๋ฐ์์ํต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ 3๊ฐ์ง ์ญํ ๋ก ๊ตฌ๋ถํ ๊ฐ๋ฐ ๋ฐฉ๋ฒ๋ก ์ ๋๋ค.
Model: ๋น์ฆ๋์ค ๋ก์ง ์ํ ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌView: Model์ด ์ฒ๋ฆฌํ ๋ฐ์ดํฐ์ ์๊ฐํ = ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ฃผ๋ ํ๋ฉดController: Model๊ณผ View์ ์ฌ์ด ์ฐ๊ฒฐ ๋ฐ ๋ฐ์ดํฐ ํ๋ฆ ์ ์ด
์ญํ ์ 3๊ฐ์ง(์ฌ์ฉ์๊ฐ ๋ณด๋ ํ์ด์ง, ๋ฐ์ดํฐ ์ฒ๋ฆฌ, ์ด๋ฅผ ์ค๊ฐ์์ ์ ์ดํ๋ ์ปจํธ๋กค๋ฌ)๋ก ๊ตฌ๋ถํ์ฌ ๋ด๋นํจ์ผ๋ก์จ ์๊ธฐ๋ ์ด์ ์ด ๋ง์ต๋๋ค.
- ์ฝ๋ ์์ ์ด ์ฉ์ดํฉ๋๋ค.
- ์ ์ง๋ณด์ ๋๋ ํ์ฅ์ฑ ๋ณด์ฅ
- ๊ฒฐํฉ๋๋ฅผ ๋์ผ ์ ์์ต๋๋ค.
- ๊ด๋ จ ์๋ ๊ธฐ๋ฅ์ ํ๋์ Controller๋ก ๋ฌถ๊ฑฐ๋, ํน์ Model๊ณผ ๊ด๋ จ ์๋ View ๊ทธ๋ฃนํ๊ฐ ๊ฐ๋ฅ
- ๋จ, ํ๋์ Controller์ ๋ค์์ Model๊ณผ View๊ฐ ์ฐ๊ฒฐ๋์ด ์๋ ์ํฉ์ด ์๊ธธ ์ ์์ด, ์๋ก์ ์์กด์ฑ ๋ฌธ์ ๋ฐ์ ๊ฐ๋ฅ
์ฌ์ฉ์๊ฐ ์
๋ ฅ์ ๋ด๋นํ๋ View๋ฅผ ํตํด ์์ฒญ์ ๋ณด๋ด๋ฉด ํด๋น ์์ฒญ์ Controller๊ฐ ๋ฐ๊ณ ,
Controller๋ Model์ ํตํด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ํด๋น ๋ฐ์ดํฐ๋ฅผ ๋ฐํ์ผ๋ก ์ถ๋ ฅ์ ๋ด๋นํ๋ View๋ฅผ ์ ์ดํด์ ์ฌ์ฉ์์๊ฒ ์ ๋ฌํฉ๋๋ค.
- Model์ด๋?
- ๋๋ฉ์ธ ๊ฐ์ฒด ๋๋ DTO๋ก ํ๋ฉด์ ์ ๋ฌํ ๋๋ ํ๋ฉด์์ ์ ๋ฌ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ ๊ฐ์ฒด
- Model์ ์ํ์ ๋ณํ๊ฐ ์์ ๋ ์ปจํธ๋กค๋ฌ์ View์ ์ด๋ฅผ ํต๋ณดํ ์๋ ์๊ณ , ๋ฐ๋๋ก Controller์ View๊ฐ ์ง์ Model์ ์ํ๋ฅผ ์ฝ์ด์ค๊ธฐ๋ ํ๋ค.
- Model์ ์ฌ์ฉ์์๊ฒ ์ด๋ป๊ฒ ๋ณด์ผ์ง ์ ๊ฒฝ ์ฐ์ง ์์๋ ๋๊ณ , ์์ํ๊ฒ public ํจ์๋ก๋ง ์ด๋ฃจ์ด์ ธ ์๋ค. (POJO)
- ๊ตฌ์ฑ ์์
- Service : DB ํธ๋์ญ์ ์ฒ๋ฆฌ์ ๋๋ฉ์ธ์๊ฒ ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ๋ฅผ ์์
- ๋๋ฉ์ธ ๊ฐ์ฒด : ๋น์ฆ๋์ค ๋ก์ง์ ์ํ
- DAO(or Repository) : DB CRUD
- DTO : Layer๊ฐ ํต์ ์ฉ
- Controller๋?
- ์ฌ์ฉ์ ์ ๋ ฅ์ ๋ฐ์ Model ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๊ฑฐ๋, Model ๊ฐ์ฒด๋ฅผ View์ ์ ๋ฌํ๋ ์ญํ
- ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ฐ์์ ๋ ๊ทธ ์์ฒญ์ ๋ํด ์ค์ ์ ๋ฌด๋ฅผ ์ํํ๋ Model ์ปดํฌ๋ํธ ํธ์ถ
- ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด, Model ํธ์ถ ์ ์ ๋ฌํ๊ธฐ ์ฝ๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ์ ํ ๊ฐ๊ณต
- Model์ด ์ ๋ฌด ์ํ์ ์๋ฃํ๋ฉด, ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๊ณ ํ๋ฉด์ ์์ฑํ๋๋ก View์ ์ ๋ฌํ๋ค.
- ์ฑ
์
- ์ ๋ ฅ๊ฐ ๊ฒ์ฆ
- ์ ๋ ฅ ๋ฐ์ ๋ฐ์ดํฐ๋ก Model ๊ฐ์ฒด ๋ณ๊ฒฝ
- ๋ณ๊ฒฝ๋ Model ๊ฐ์ฒด๋ฅผ View์ ์ ๋ฌ
- Service Layer์ ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ ์์ฒญ โ Service๋ ๋๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ํตํด ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ ํ ๊ฒฐ๊ณผ ๋ฐํ
- View๋?
- ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ฃผ๋ ์ญํ
- ๋ค์ํ ํํ๋ก ๋ณด์ฌ์ค ์ ์๋ค.
- ์์
- HTML, JSON, XML, JSP, Thymleaf ๋ฑ
Front Controller ํจํด์ด๋ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํ๋๊ฐ ์๋ธ๋ฆฟ ์ปจํ
์ด๋์ ์ ์ผ ์์์ ์๋ฒ๋ก ๋ค์ด์ค๋ ํด๋ผ์ด์ธํธ์ ๋ชจ๋ ์์ฒญ์ ๋ฐ์ ์ฒ๋ฆฌํ๋๋ก ๋์์ธํ ํจํด์
๋๋ค.
-
๊ตฌ์กฐ ๋น๊ต
- ๊ธฐ์กด ํจํด
- ๊ฐ ํด๋ผ์ด์ธํธ๋ค์ Controller A, B, C์ ๋ํด ๊ฐ๊ฐ ํธ์ถํ๋ค.
- ๊ณตํต ์ฝ๋๋ค์ ๋ณ๋๋ก ์ฒ๋ฆฌ๋์ด ์์ง ์๊ณ ๊ฐ Controller์ ํฌํจ๋์ด ์๋ค.
- ๋จ์ :
- ์์ฒญ์ ์ํํ ๋๋ง๋ค ๋งค๋ฒ ์ค๋ ๋๋ฅผ ์์ฑํด์ผ ํ๋ฏ๋ก, ๋ฉํฐ ์ค๋ ๋ฉ์ ๋ค๋ค์ผ ํ๋ค๋ ์ด๋ ค์์ด ์๋ค. (๊ด๋ฆฌ์ ์ธก๋ฉด)
- ํธ๋ค๋ฌ์ ๊ณตํต ๋ก์ง์ด ๋งค๋ฒ ์ค๋ณต๋๋ค. (๊ฐ๋ฐ์ ์ธก๋ฉด)
- Front Controller(๋ํ ์ปจํธ๋กค๋ฌ) ํจํด
-
ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์์ฒญ์ด ๋ค์ด์ฌ ๊ฒฝ์ฐ, Front Controller๊ฐ ๊ฐ ์์ฒญ์ ๋ง๋ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฐพ์์ ํธ์ถํ๋ค.
-
๊ณตํต ์ฝ๋์ ๋ํด์๋ Front Controller์์ ์ฒ๋ฆฌํ๊ณ , ์๋ก ๋ค๋ฅธ ์ฝ๋๋ค๋ง ๊ฐ Controller์์ ์ฒ๋ฆฌํ ์ ์๋๋ก ํ๋ค.
-
View์์ ๋ค์ด์ค๋ ๋ชจ๋ ์์ฒญ์ ๋ด๋นํ์ฌ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๋ ๋ชจ๋ ์์ฒญ์ ์ผ๊ด์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
-
์ฅ์
- ๊ณตํต๋ ๋ถ๋ถ์ ์ฒ๋ฆฌํด์ฃผ๋ FrontController๋ก ์ค๋ณต์ ์ค์ผ ์ ์๋ค.
- Front Controller ์ธ์ ๋ค๋ฅธ Controller์์ Servlet์ ์ฌ์ฉํ์ง ์์๋ ๋๋ค.
๐ค Spring Web MVC์์ ์์ฒญ๋ง๋ค Thread๊ฐ ์์ฑ๋์ด Controller๋ฅผ ํตํด ์์ฒญ์ ์ํํ ํ ๋ฐ, ์ด๋ป๊ฒ 1๊ฐ์ Controller๋ง ์์ฑ๋ ์ ์์๊น์?
Controller ๊ฐ์ฒด ํ๋๋ฅผ ์์ฑํ๋ฉด ๊ฐ์ฒด ์์ฒด๋ Heap์ ์์ฑ๋์ง๋ง, ํด๋น Class์ ์ ๋ณด๋ ๋ฉ์๋ ์์ญ์ ์ ์ฅ๋ฉ๋๋ค.
๋ชจ๋ Thread๋ ๊ฐ์ฒด์ Binary Code ์ ๋ณด๋ฅผ ๊ณต์ ํ ์ ์์ต๋๋ค.
๊ณต์ ๋๋ ์ ๋ณด๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ์ฌ ๊ตณ์ด Controller ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ์ฐ๋ ๋๋ Controller ๊ฐ์ฒด ์์ฒด๊ฐ Block๋ ํ์๊ฐ ์์ต๋๋ค.
์๋ํ๋ฉด, ๊ฐ์ฒด ๋ด๋ถ์ ์ผ๋ก ์ํ๋ฅผ ๊ฐ๋ ๊ฒ์ด ์์ผ๋, ๋ด๋ถ์ ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ผ์ด ์๊ณ ๊ทธ์ ๋ฉ์๋์ ๋ํ ์ ๋ณด๋ง โ๊ฐ์ด ๊ณต์ ํด์โ ์ฐ๋ฉด ๋๊ธฐ ๋๋ฌธ์
๋๋ค.
Controller๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ํ๋ฅผ ๊ฐ๋ ๊ฒ์ด ์์ผ๋ ๋ฉ์๋ ํธ์ถ๋ง ํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๊ตณ์ด ๋๊ธฐํํ ์ด์ ๊ฐ ์๊ณ , ๊ทธ์ ์ฒ๋ฆฌ ๋ก์ง๋ง โ๊ณต์ ๋์ดโ ์ฌ์ฉ๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ช ์ญ๋ง๊ฐ์ ์์ฒญ์ด ๋ค์ด์ค๋ ์๊ด์์ต๋๋ค.
Dispatcher Servlet์ ๋ชจ๋ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์
๋๋ค.
Spring Web MVC์ Dispatcher Servlet์ ๋์ ์๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋ธ๋ผ์ฐ์ ์ ๋ชจ๋ ์์ฒญ์ด Dispatcher Servlet์๊ฒ ์ ๋ฌ๋ฉ๋๋ค.
- Dispatcher Servlert์ด ์์ฒญ์ ๋ฐ์ผ๋ฉด ๊ทธ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋ Hanlder์ ์ด๋ฆ์ Handler Mapping ์๊ฒ ๋ฌผ์ด๋ด ๋๋ค.
- Handler Mapping์ ์์ฒญ URL์ ๋ณด๊ณ Handler๋ฅผ ํ๋จํ๊ณ Handler Name์ ๊ณผ ํจ๊ป ์ ์ด๊ถ์ Dispacher Servlet์๊ฒ ๋๊ฒจ์ค๋๋ค.
- Handler ์คํ ์ ์ ์ ์ฒ๋ฆฌ, ํ์ฒ๋ฆฌ๋ก ์คํํด์ผํ ์ธํฐ์ ํฐ ๋ชฉ๋ก์ ๊ฒฐ์ ํฉ๋๋ค.
- Service์ ๋น์ฆ๋์ค ๋ก์ง์ ์คํํฉ๋๋ค.
- Handler๋ ๋๋๋งํด์ผํ๋ View Name์ ํ๋จํด์ Dispatcher Servlet์ ์ ์กํฉ๋๋ค.
- Dispatcher Servlet์ View name์ View Resolver์ ์ ๋ฌํฉ๋๋ค.
- View Resolver๋ ์ ๋ฌ๋ฐ์ ๊ฐ์ผ๋ก ์ ์ ํ View๋ฅผ ์์ฑํ์ฌ Dispatcher Servlet์ ์ ๋ฌํฉ๋๋ค.
- Dispatcher Servlet์ View์ Model๊ณผ Controller๋ฅผ ์ ๋ฌํฉ๋๋ค.
- View๋ก ๋ถํฐ ๋ฐ์ ์๋ต์ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌํฉ๋๋ค.
์คํ๋ง MVC ๋ชจ๋์์ ์ธํฐ์
ํฐ๋ฅผ ์ด์ฉํด์ ์ปจํธ๋กค๋ฌ๊ฐ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ ํน์ ํ์ ๋ํ ๋ก์ง์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
์ปจํธ๋กค๋ฌ๊ฐ ์คํ๋๊ธฐ ์ ์ ์ธํฐ์
ํฐ๋ฅผ ์คํํ ์ ์์์ผ๋ก ์ฃผ๋ก ํน์ ์์ฒญ์ ๋ํ ๊ณตํต ๋ก์ง ์ ์ฉ์ด ํ์ํ ๊ฒฝ์ฐ์ ์ ์ฉํฉ๋๋ค.
DispatcherServlet์ ์์ฒญ์ ๋์ํ ์ ์๋ Controller, ViewResolver, HandlerMapping๊ณผ ๊ฐ์ ์คํ๋ง ๋น์ ๊ตฌ์ฑํฉ๋๋ค.
- DispatcherSerlvet์ ๊ธฐ๋ณธ ์ ๋ต
- DispachersServlet.propertes ์ค์ ์ ๋ฐ๋ผ๊ฐ๋ค.
- MutilpartResolver
- ํ์ผ ์ ๋ก๋ ์์ฒญ ์ฒ๋ฆฌ์ ํ์ํ ์ธํฐํ์ด์ค
- HttpServletRequest๋ฅผ MutilpartHttpServletRequest๋ก ๋ณํํด์ฃผ์ด ์์ฒญ์ด ๋ด๊ณ ์๋ field์ ๊บผ๋ผ์ ์๋ API ์ ๊ณตํ๋ค.
- LocaleResolver
- ํด๋ผ์ด์ธํธ์ ์์น ์ ๋ณด๋ฅผ ํ์ ํ๋ ์ธํฐํ์ด์ค
- ๊ธฐ๋ณธ ์ ๋ต์ ์์ฒญ accept-language๋ฅผ ๋ณด๊ณ ํ๋จํ๋ค.
- HanderMapping
- ์์ฒญ์ ์ฒ๋ฆฌํ ํธ๋ค๋ฌ๋ฅผ ์ฐพ๋ ์ธํฐํ์ด์ค
- HandlerAdapter
- HandlerMapping์ด ์ฐพ์๋ธ ํธ๋ค๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋ ์ธํฐํ์ด์ค
- ์คํ๋ง MVC ํ์ฅ๋ ฅ์ ํต์ฌ
(์ฌ๊ธฐ์, controller๋ฅผ ํธ์ถํ๋๋ฐ, controller๊ฐ ์คํ๋๊ธฐ ์ Interceptor๋ฅผ ์คํํด์ ํน์ ์์ฒญ์ ๋ํ ๊ณตํต ๋ก์ง ์ ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.)
- ViewResolver
- ๋ทฐ ์ด๋ฆ์ ํด๋นํ๋ ๋ทฐ๋ฅผ ์ฐพ์๋ด๋ ์ธํฐํ์ด์ค
- FlashMapManager
- FlashMap ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ ์ฅํ๋ ์ธํฐํ์ด์ค
- FlashMap์ ์ฃผ๋ก ๋ฆฌ๋ค์ด๋ ์
์ ์ฌ์ฉํ ๋ ์์ฒญ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ณ ์ ๋ฆฌํ ๋ ์ฌ์ฉํ๋ค.
AOP๋ Aspect Oriented Programming, ๊ด์ ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์๋ฏธํฉ๋๋ค.
๊ด์ ์งํฅ์ด๋, ์ด๋ค ๋ก์ง์ ๊ธฐ์ค์ผ๋ก ํต์ฌ์ ์ธ ๊ด์ , ๋ถ๊ฐ์ ์ธ ๊ด์ ์ผ๋ก ๋๋์ด์ ๊ฐ๊ฐ ๋ชจ๋ํํ๋ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ์ ์๋ฏธํฉ๋๋ค.
๋ฐ๋ผ์ AOP๋ ํต์ฌ๊ธฐ๋ฅ๊ณผ ๋ถ๊ฐ๊ธฐ๋ฅ์ ๋๋์ด์ ์ค๊ณ, ๊ตฌํํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
ํ์์ ์ด์ง๋ง ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์ฉ๋๋ ์ฝ๋, log ์ถ๋ ฅ์ด๋, ์์ธ์ฒ๋ฆฌ ๊ฐ์ ๋ถ๋ถ์ ๋ชจ๋ํ ์์ผ, ๋ฆฌํฉํ ๋ง๊ณผ ์ ์ง๋ณด์์ ์ด์ ์ ์ฃผ๊ธฐ ๋๋ฌธ์
๋๋ค.
์คํ๋ง์์ AOP๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ๊ฐ๋ฐ ์ฝ๋์์๋ ๋น์ง๋์ค ๋ก์ง์ ์ง์คํ ์ ์๊ณ , ๋ฐํ์ ์คํ ์ ๋ถ๊ฐ๊ธฐ๋ฅ์ ๋น์ง๋์ค ๋ก์ง ์๊ณผ, ๋ค ์ํ๋ ์ง์ ์์
๊ณตํต ๊ด์ฌ์ฌ๋ฅผ ์ํํ๊ฒ ํ์ฌ ์ค๋ณต์ฝ๋๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
์คํ๋ง AOP์์๋ Advice๊ฐ ์ ์ฉ๋๋ 5๊ฐ์ง ์์ ์ ์ ๊ณตํฉ๋๋ค.
- @Around() : ์ฒซ๋ฒ์งธ๋ก, Around() ์ด๋ ธํ ์ด์ ์ ํต์ฌ๊ธฐ๋ฅ ์ ๊ณผ ํ ๋ชจ๋ ์คํ๋จ์ ์๋ฏธํฉ๋๋ค.
- @Before() : Before() ์ด๋ ธํ ์ด์ ์ ํต์ฌ๊ธฐ๋ฅ ํธ์ถ์ ์ ์คํ๋จ์ ์๋ฏธํฉ๋๋ค.
- @After() : ์ธ๋ฒ์งธ๋ก, After() ์ด๋ ธํ ์ด์ ์ 'ํต์ฌ๊ธฐ๋ฅ'์ ์ํ ์ฑ๊ณต ์ฌ๋ถ์ ์๊ด์์ด ์ํ ํ ์ธ์ ๋ ์คํ๋จ์ ์๋ฏธํฉ๋๋ค.
- @AfterReturning() : AfterReturning()์ 'ํต์ฌ๊ธฐ๋ฅ'์ ํธ์ถ ์ฑ๊ณต์์๋ง ์คํ๋ ๊ฒ์์ ์๋ฏธํฉ๋๋ค.
- @AfterThrowing() : ๋ง์ง๋ง์ผ๋ก, AfterThrowing()์ 'ํต์ฌ๊ธฐ๋ฅ' ํธ์ถ ์คํจ ์, ์ฆ ์์ธ(Exception) ๋ฐ์ํ ๊ฒฝ์ฐ๋ง ๋์ํ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์์ ์ฝ๋
@Aspect
@Component
public class Advice {
/*
* Before : ํด๋์ค์ ๋ฉ์๋ ์คํ ์
* within : BoardController ํด๋์ค๋ฅผ ์ง์
*/
@Before("within (com.wipia.study.controller.BoardController)")
public void beforeAdvice() {
System.out.println("BoardController Before");
}
/*
* After : ๋ฉ์๋ ์คํ ํ
* execution : getBoardList ๋ฉ์๋ ์ง์ * ๋ก ๋ชจ๋ ๋ฉ์๋ ์ง์ ๊ฐ๋ฅ
* ์ ๊ทผ์ง์ ์ : ์๋ต ๊ฐ๋ฅ ex) public, private
* * : ๋ณํ ํ์
*
*/
@After("execution(* com.wipia.study.controller.BoardController.getBoardList(..))")
public void afterAdvice() {
System.out.println("after getBoardList");
}
/*
* AfterThrowing : ์์ธ ๋ฐ์ ์
* ๋ชจ๋ ํด๋์ค์์ ๋ฉ์๋ ํธ์ถ ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋ ๋์
*/
@AfterThrowing(pointcut="execution(* com.wipia*..*.*(..))", throwing="e")
public void afterThrowingAdvice(Exception e) {
System.out.println("์๋ฌ๋ค : "+e);
}
/*
* ๋ชจ๋ ๋ฉ์๋ ์คํ์ ์ผ๋ง๋ ๊ฑธ๋ฆฌ๋์ง ์๊ฐ ์ถ๋ ฅ
*/
@Around("execution (* com.wipia..*.*(..))")
public Object time(ProceedingJoinPoint pjp) {
long start = System.currentTimeMillis();
System.out.println("--- Target : "+pjp.getTarget());
System.out.println("--- Parameter : "+Arrays.toString(pjp.getArgs()));
Object result = null;
try {
result=pjp.proceed();
}catch (Throwable e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("--- Time : "+(end-start));
return result;
}
}- ํ๋ก์ ํจํด ๊ธฐ๋ฐ์ด๊ธฐ ๋๋ฌธ์, ์ ๊ทผ ์ ์ด๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- ํ๋ก์๊ฐ ํธ์ถ์ ์ธํฐ์ ํฐํด์ ํต์ฌ ๋ก์ง ์ ๊ณผ ํ์ ๋ถ๊ฐ๊ธฐ๋ฅ์ ์ํํ ์ ์์ต๋๋ค.
- ํต์ฌ ๊ธฐ๋ฅ์ ๋ฉ์๋๊ฐ ํธ์ถ๋๋ ๋ฐํ์ ์์ ์๋ง ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ ์ฉํ ์ ์์ต๋๋ค.
์ด๋ค ๊ฐ์ฒด์ ๋ํ ์ ๊ทผ์ ์ ์ดํ๊ฑฐ๋ ๋ถ๊ฐ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ์ฉ๋๋ก ์ค์ ๊ฐ์ฒด๋ฅผ ๋์ ํ๋ ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ ํจํด์
๋๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ์ธํฐํ์ด์ค ํ์
์ผ๋ก ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๊ฒ ๋๊ณ , ํ๋ก์๋ ํต์ฌ ๊ธฐ๋ฅ์ ๊ฐ๋ ์ค์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ธ์ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ฒ ๋ฉ๋๋ค. ์ด๋ฐ ํน์ง ๋๋ถ์ ํ๋ก์ ํจํด์ ์ ๊ทผ์ ์ ์ดํ ์ ์๊ณ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๊ฒ ๋ฉ๋๋ค.
- Aspect : ํฉ์ด์ง ๊ด์ฌ์ฌ๋ฅผ ๋ชจ๋ํ ํ ๊ฒ์ ๋๋ค. ์ฃผ๋ก ๋ถ๊ฐ๊ธฐ๋ฅ์ ๋ชจ๋ํํจ์ ์๋ฏธํฉ๋๋ค.
- Target : Aspect๋ฅผ ์ ์ฉํ๋ ๊ณณ์ธ ์๋ฏธํฉ๋๋ค. Target์ ์ฃผ๋ก ํด๋์ค, ๋ฉ์๋ ๋ฑ์ด ๋ฉ๋๋ค.
- Advice : ์ค์ง์ ์ผ๋ก ์ด๋ค ์ผ์ ํด์ผํ ์ง์ ๋ํ ๊ฒ์ ์๋ฏธํ๋น๋ค.Advice๋ ์ค์ง์ ์ธ ๋ถ๊ฐ๊ธฐ๋ฅ์ ๋ด์ ๊ตฌํ์ฒด์ ๋๋ค.
- JoinPoint : Advice๊ฐ ์ ์ฉ๋ ์์น, ๋ผ์ด๋ค ์ ์๋ ์ง์ , ๋ฉ์๋ ์ง์ ์ง์ , ์์ฑ์ ํธ์ถ ์์ , ํ๋์์ ๊ฐ์ ๊บผ๋ด์ฌ ๋์ ์์ ์ ๋งํฉ๋๋ค. ์ฑ์ ์คํํ ๋ ํน์ ์์ ์ด ์์๋๋ ์์ ์ ๋๋ค.
- PointCut : JoinPoint๊ฐ ์ ์ฉ๋๋ ๋์, Adivice๊ฐ ์คํ๋ ์ง์ ์ ์ค์ ํฉ๋๋ค.
- ์ฒซ ๋ฒ์งธ๋ก, Servlet Filter๋ฅผ ์ฌ์ฉํ์ฌ ์ปค์คํ ํ CORS ์ค์ ํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
- ๋ ๋ฒ์งธ๋ก, Controller ํด๋์ค์ @Crossorigin ์ด๋ ธํ ์ด์ ์ ํตํด ํด๊ฒฐํ ์ ์์ต๋๋ค.
- ์ธ ๋ฒ์งธ๋ก,WebMvcConfiguer๋ฅผ ๊ตฌํํ Configuration ํด๋์ค๋ฅผ ๋ง๋ค์ด์ addCorsMappings()๋ฅผ ์ฌ์ ์ํ ์๋ ์์ต๋๋ค.
- ๋ง์ง๋ง์ผ๋ก, Spring Security์์ CorsConfigurationSource๋ฅผ Bean์ผ๋ก ๋ฑ๋กํ๊ณ config์ ์ถ๊ฐํด์ค์ผ๋ก์จ ํด๊ฒฐํ ์ ์์ต๋๋ค.
CORS(Cross-Origin-Resource-Sharing)๋ Origin์ด ๋ค๋ฅธ ๊ฒฝ์ฐ(Cross-Oirgin) ๋ฆฌ์์ค๋ฅผ ๊ณต์ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
ํ์ง๋ง ์น๋ธ๋ผ์ฐ์ ๋ ์๋ ๋์ผ ์ถ์ฒ ์์น(Same Origin Policy)๋ฅผ ๋ณด์์ ๊ธฐ๋ณธ์ผ๋ก ํฉ๋๋ค.
๋ฐ๋ผ์ CORS์๋ฌ๋, ๋์ผํ ์ถ์ฒ์ Origin, ์ฆ ์คํค๋ง, Host, Port๊ฐ ๊ฐ์์ผ๋ง ๋ฆฌ์์ค๋ฅผ ๊ณต์ ํ ์ ์๋ค๋ ๋ณด์ ์ ์ฑ
๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค.
์๋ฒ์ ์๋ต์ ๋ณด๋ด๊ธฐ ์ ์ Access-Control-Allow-Origin ํค๋๋ฅผ ์ฃ๋ ํํฐ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- ๋น์ผ๋ก ๋ฑ๋ก๋ CorsFilter ํด๋์ค๋ฅผ ์์ฑํฉ๋๋ค.
- ํด๋น ํด๋์ค์ doFilter๋ฅผ ์ง์ ์ค๋ฒ๋ผ์ด๋ํด์ Options ๋ฉ์๋์ response๋ก Access-Control-Allow-Originํค๋์ ํ์ฉ๋ Origin์ด๋ผ๋ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
์์์ฝ๋
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:5500");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods","*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization");
if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
}else {
chain.doFilter(req, res);
}
}
@Override
public void destroy() {
}
}- Controller ํด๋์ค ์๋จ์ด๋ Controller Mapping ๋ฉ์๋ ์๋จ์ CrossOrigin(origins="๋๋ฉ์ธ url")์ ์ด๋ ธํ ์ด์ ์ผ๋ก ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- CorsFilter๋ฅผ ์ง์ ๊ตฌํํด์ ์ฌ์ฉํ๋ ๊ฒ ๋ณด๋ค, ์ด๋ ธํ ์ด์ ๋ง ๋ถํ๋ฉด ๋๊ธฐ์ ๋ ๊ฐํธํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์์์ฝ๋
@CrossOrigin(origins = "http://127.0.0.1:5500/") // ์ปจํธ๋กค๋ฌ ํด๋์ค์ ์๋จ
@RequiredArgsConstructor
@RestController
public class ArticleRestController {
public final ArticleRepository articleRepository;
public final ArticleService articleService;
public final LocationDistance location;
@CrossOrigin(origins = "http://127.0.0.1:5500/") // ์ปจํธ๋กค๋ฌ ๋งตํ ๋ฉ์๋ ์๋จ
@GetMapping("/api/articles/{query}")
public ResponseEntity<List<Article>> getArticles (@PathVariable("query") String query) {
List<Article> articles = articleRepository.findAllByTitleContains(query);
return ResponseEntity.ok().body(articles);
}
}- WebMvcConfig ํด๋์ค๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- WebMvcConfiguer๋ฅผ implementํ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ , @Configuration ์ด๋ ธํ ์ด์ ์ผ๋ก ์ดํ๋ฆฌ์ผ์ด์ ์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- allowedOrigins, allowedMethods ๋ฉ์๋๋ฅผ ํตํด cors๋ฅผ ์ค์ ํด์ค ์ ์์ต๋๋ค.
- ๊ฐ๋จํ ์ฝ๋๋ก ์ ์ฒด๋ฒ์์ CORS๋ฅผ ์ค์ ํด ์ค๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
์์์ฝ๋
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:5500", "http://127.0.0.1:5500")
.allowedMethods("POST", "PUT", "GET", "HEAD", "OPTIONS", "DELETE");
}
}Java Bean์ ๋ฐ์ดํฐ ํํ์ ๋ชฉ์ ์ผ๋ก Java๋ก ์์ฑ๋ ํด๋์ค์
๋๋ค.
private์ผ๋ก ํ๋๋ฅผ ์ ์ธํ๊ณ ์ ๋ฌ ์ธ์๊ฐ ์๋ ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ๊ฐ์ต๋๋ค.
getter์ setter๋ก๋ง ์ ๊ทผํ ์ ์๋ ํด๋์ค์ ๋ฉค๋ฒ ๋ณ์์ธ Properties๊ฐ ์์ต๋๋ค.
Spring IoC ์ปจํ ์ด๋๊ฐ ์ธ์คํด์คํ, ๊ด๋ฆฌ, ์์ฑํ๋ ์๋ฐ ๊ฐ์ฒด์ด๋ฉฐ ApplicationContext๊ฐ ๋ง๋ค์ด์ ๊ทธ ์์ ๋ด๊ณ ์๋ ๊ฐ์ฒด์ ๋๋ค.
๋ฐ๋ผ์ ๊ธฐ์กด ์๋ฐ ํ๋ก๊ทธ๋๋ฐ์ฒ๋ผ Class ์์ฑ ํ new ์ฐ์ฐ์๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์๋๋ผ
ApplicationContext.getBean()์ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์คํ๋ง์ผ๋ก๋ถํฐ ๊ฐ์ฒด๋ฅผ ์ป์ต๋๋ค.
๊ฐ์ฒด ์์ฑ โ ์์กด ์ค์ โ ์ด๊ธฐํ โ ์ฌ์ฉ โ ์๋ฉธ ์์๋ก ๋ผ์ดํ ์ฌ์ดํด์ ์ง๋๋๋ค.
1.์คํ๋ง ์ปจํ
์ด๋๊ฐ ์ด๊ธฐํ ๋ ๋ ๋จผ์ Bean ๊ฐ์ฒด๋ฅผ ์ค์ ์ ๋ณด์ ๋ง์ถฐ ํ์, ์์ฑํฉ๋๋ค.
2.Bean์ผ๋ก ๋ฑ๋กํ ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํ ํ๊ณ ์์กด ๊ด๊ณ๋ฅผ ์ฃผ์
ํฉ๋๋ค.
3.ํด๋น ํ๋ก์ธ์ค๊ฐ ์๋ฃ๋๋ฉด Bean ๊ฐ์ฒด๊ฐ ์ง์ ํ ๋ฉ์๋๋ฅผ ํธ์ถํด์ ์ด๊ธฐํ ํฉ๋๋ค.
4.๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ๋ค ์ปจํ
์ด๋๊ฐ ์ข
๋ฃ๋ ๋ Bean์ด ์ง์ ํ ๋ฉ์๋(destroy method)๋ฅผ ํธ์ถํด ์๋ฉธํฉ๋๋ค.
Scope๋ Bean์ด ์กด์ฌํ๊ณ ๊ด๋ฆฌ๋๋ ๋ฒ์๋ฅผ ์๋ฏธํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก Sington Scope๋ก ๊ด๋ฆฌํ๊ฒ ๋๋๋ฐ, Singleton์ ์คํ๋ง ์ปจํ ์ด๋์ ์์๊ณผ ์ข ๋ฃ๊น์ง ๊ฐ์ฅ ๋์ ๋ฒ์๋ก ํ ๊ฐ์ฒด๊ฐ ์ ์ง๋ฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ๋ ์ JVM ์์์ Spring์ด Bean๋ง๋ค ํ๋์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฏ๋ก ๊ฐ๋ฐ์๋ค์ Spring์ ํตํด Bean์ ์ ๊ณต๋ฐ์ผ๋ฉด ์ธ์ ๋ ์ฃผ์ ๋ฐ์ Bean์ ๋์ผํ ๊ฐ์ฒด๋ผ๋ ๊ฐ์ ํ์์ ์ถ๋ฐํฉ๋๋ค.
๋ฐ๋ฉด, ProtoType Scope๋ Bean์ ์์ฑ๊ณผ ์์กด ์ค์ ๊น์ง๋ง ๊ด์ฌํ๋ ๋งค์ฐ ์งง์ ์ค์ฝํ์
๋๋ค.
๋ฐ๋ผ์ ๋ชจ๋ ์์ฒญ์์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ฒ ๋ฉ๋๋ค.
1.singleton : ์คํ๋ง ์ปจํ
์ด๋์ ์์๊ณผ ์ข
๋ฃ๊น์ง ๋จ ํ๋์ ๊ฐ์ฒด๋ง ์ฌ์ฉํ๋ ๋ฐฉ์
prototype: ๋ชจ๋ ์์ฒญ์์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฐฉ์
๐ค Bean/Component ์ด๋ ธํ ์ด์ ์ ๋ํด์ ์ค๋ช ํด์ฃผ์๊ณ , ๋์ ์ฐจ์ด์ ์ ๋ํด ์ค๋ช ํด์ฃผ์ธ์.
-
@Bean
๊ฐ๋ฐ์๊ฐ ์ง์ ์ ์ด๊ฐ ๋ถ๊ฐ๋ฅํ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ ๋ ์ฌ์ฉํฉ๋๋ค.
@Configuration์ ์ ์ธํ ํด๋์ค ๋ด๋ถ์์ ์ฌ์ฉํ๋๋ฐ,
์ด๋ ๊ฐ๋ฐ์๊ฐ ์์ฑํ ๋ฉ์๋๋ฅผ ํตํด ๋ฐํ๋๋ ๊ฐ์ฒด๋ฅผ Bean์ผ๋ก ๋ง๋ค๊ธฐ ๋๋ฌธ์ ๋๋ค.
// ๊ฐ๋ฐ์๊ฐ ์ง์ ์ ์ด๊ฐ ๋ถ๊ฐ๋ฅํ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ @Configuration public class ExampleConfig { @Bean public ArrayList<String> array(){ return new ArrayList<String>(); } }
// ๊ฐ๋ฐ์๊ฐ ๋ง๋ค์ด์ค ํด๋์ค๋ฅผ importํด ์ฌ์ฉํ ๊ฒฝ์ฐ @Configuration public class ExampleConfig { @Bean(name="mybean") public Product aaa(){ Battery p1 = new Battery("AAA", 2.5); p1.setRechargeable(true); return p1; }
-
@Component
๊ฐ๋ฐ์๊ฐ ์ง์ ์์ฑํด ์ปจํธ๋กค ํ ์ ์๋ Class๋ฅผ Bean์ผ๋ก ๋ฑ๋กํ ๋ ์ฌ์ฉํฉ๋๋ค.
@Component(value="mybean") public class Example { puiblic Example(){ System.out.println("Hello world"); } }
- ๊ฐ์ฒด์ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋ง์ฝ ์ธ๋ถ์์ ๋ชธ๋ฌด๊ฒ๋ผ๋ ํ๋์ ์ง์ ์ ๊ทผํ๋ค๋ฉด 0๋ณด๋ค ๋ฎ์ ๊ฐ์ ์ค ์๋ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๊ฐ์ฒด์ ๋ฌด๊ฒฐ์ฑ์ด ๊นจ์ง๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด Getter/Setter๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ์ง์ผ์ค๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋ง์ฝ ์ธ๋ถ์์ ๋ชธ๋ฌด๊ฒ๋ผ๋ ํ๋์ ์ง์ ์ ๊ทผํ๋ค๋ฉด 0๋ณด๋ค ๋ฎ์ ๊ฐ์ ์ค ์๋ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๊ฐ์ฒด์ ๋ฌด๊ฒฐ์ฑ์ด ๊นจ์ง๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด Getter/Setter๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ์ง์ผ์ค๋๋ค.
๋ฐ์ดํฐ์ ์ ํ์ฑ๊ณผ ์ผ๊ด์ฑ์ ์ ์งํ๊ณ ๋ณด์ฆํ๋ ๊ฒ์ ๋งํฉ๋๋ค.
Getter, Setter๋ฅผ ์ด์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ์์ฑ ๋ฐ ์ ๊ทผ์ ํ๊ฒ ๋๋ฉด ๋ค์ด์ค๋ ๊ฐ์ ๋ฐ๋ก ์ ์ฅํ๋ ๊ฒ ์๋,
ํ๋ฒ ๊ฒ์ฆํ๊ณ ์ฒ๋ฆฌํ ์ ์๋๋ก ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ด ์ง์ผ์ง๋๋ค.
Getterย : ๋ณธ ํ๋์ ๊ฐ์ ์จ๊ธด ์ฑ ๋ด๋ถ์์ ๊ฐ๊ณต๋ ๊ฐ์ ๊บผ๋ผ ์ ์๋ค.Setterย : ํ๋๋ฅผ private๋ก ๋ง๋ค์ด ์ธ๋ถ์ ์ ๊ทผ์ ์ ํํ ํ, Setter๋ฅผ ์ฌ์ฉํด ์ ๋ฌ๋ฐ์ ๊ฐ์ ๋ด๋ถ์์ ๊ฐ๊ณตํด ํ๋์ ๋ฃ์ด์ค ์ ์๋ค.
- Getter, Setter์ ๊ฐ์ ์์ธ์ค ํจ์ ์ฌ์ฉ ์, ์์ ๊ฐ์ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ๊ณผ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- ๊ฐ์ฒด์ ํ๋๋ฅผ
private๊ณผ ๊ฐ์ ์ ๊ทผ์ ํ์๋ฅผ ๋๋ฉด์ ๊ฐ์ฒด์งํฅ์ ๋ชฉ์ ์ธ ์ ๋ณด์๋์ด ๊ฐ๋ฅํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฅผ ๋ชจ์์ ์ ๋ฌํ ์ ์์ด ํต์ ํ์๋ฅผ ๊ฐ์์ํค๊ณ , ๊ฒ์ฆ๊ณผ ๋ก์ง ์ฒ๋ฆฌ๋ฅผ ํจ์จ์ ์ผ๋ก ํ ์ ์์ต๋๋ค.
- ์ธ๋ถ์ ํต์ ํ๋ ํ๋ก๊ทธ๋จ์๊ฒ ์์ด ํธ์ถ์ ํฐ ๋น์ฉ์ด๋ฉฐ, ์ด๋ฅผ ์ค์ด๊ณ ๋์ฑ ํจ์จ์ ์ผ๋ก ๊ฐ์ ์ ๋ฌํ๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฅผ ๋ชจ์ ํ ๋ฒ์ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ด ๊ณ ์๋์๋๋ฐ, ์ด ๋ ์ด ํด๋์ค๋ฅผ DTO๋ผ๊ณ ํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฅผ ๋ฌถ์ด ๋ณด๋ด๊ธฐ ๋๋ฌธ์ ์์ ์ฑ์ด ๋๊ณ , ์ํ์๊ฐ์ ๊ฐ์์ํฌ ์ ์์ต๋๋ค.
DTO๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ์๋ฐ Domain ๊ฐ์ฒด(๋ฐ์ดํฐ)์ ์ง์ ์ ์ผ๋ก ์ ๊ทผํ์ง ์์์ผ๋ก์จ, ์๋์ ๊ฐ์ ํธ๋ฆฌํจ์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
โ ๋ฐ์ดํฐ๋ฅผ ์๋ ๋ฐ ๋ณดํธํ ์ ์์ต๋๋ค.
โก DTO๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๊ฒฐํ๊ฒ ์ํ๋ ์ ๋ณด๋ง์ ์ ๊ณตํด์ค ์ ์์ต๋๋ค.
โข Entity์ ์ ๋ณด๋ฟ๋ง ์๋๋ผ, ๊ฐ๋ฐ์๊ฐ ์ํ๋ ํ์์ ๋ฐ์ดํฐ๋ค์ ์ถ๊ฐํ์ฌ ์ ๋ณด๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์์ต๋๋ค.
DTO(Data Transfer Object, ๋ฐ์ดํฐ ์ ์ก ๊ฐ์ฒด)๋ ๋ฐ์ดํฐ ๊ตํ์ ์ํด ์ฌ์ฉํ๋ ๊ฐ์ฒด๋ก, DB์ ๋ฐ์ดํฐ๋ฅผ Controller ํน์ Service๋ก ๋ณด๋ผ ๋ ์ฌ์ฉํฉ๋๋ค.DAO(Data Access Object, ๋ฐ์ดํฐ ์ ๊ทผ ๊ฐ์ฒด)๋ ์ค์ ๋ก ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฐ์ฒด๋ก, DB์ ์ ๊ทผํ๋ ๋ก์ง๊ณผ ๋น์ฆ๋์ค ๋ก์ง์ ๋ถ๋ฆฌํ๊ธฐ ์ํ ๊ฐ์ฒด๋ก ์ฌ์ฉ๋ฉ๋๋ค.
์คํ๋ง์์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ 3๊ฐ์ง๊ฐ ์์ต๋๋ค.
์ ํํ๋ DispatcherServlet์์ ๋ฐ์ํ๋ ์์ธ๋ฅผ HandlerExceptionResolver๊ฐ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ๋ค์ ๋๋ค.
- ๋ฉ์๋ ๋จ์์, try/catch๋ฌธ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฃผ๋ก Check Exception์ ์ฒ๋ฆฌํด์ผํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํฉ๋๋ค.
- ์ปจํธ๋กค๋ฌ๋จ์์ @ExceptionHandler ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฃผ๋ก Controller์ ๋ฉ์๋์์ throw๋ Exception์ ๋ํด ๊ณตํต์ ์ธ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๊ฒํฉ๋๋ค.
- ์ปค์คํ
ํ Exception ํด๋์ค๋ฅผ ๋ง๋ค์ด Global Level์์, ์ปจํธ๋กค๋ฌ ์ดํ Client์๊ฒ ์ ๋ฌ๋๊ธฐ ์ ์ ์ฒ๋ฆฌํ๋ AOP ๋ฐฉ์์ด ์์ต๋๋ค.
์คํ๋ง์์ @ExceptionHandler ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ํน์ ์์ธ ํด๋์ค๋ฅผ ์ง์ ํด์ฃผ๋ฉด, ํด๋น ์์ธ๊ฐ ๋ฐ์ํ์ ๋ ๋ฉ์๋์์ ์ ์ํ ๋ก์ง์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
AOP ๊ด์ ์์ @RestControllerAdvice ์ด๋ ธํ ์ด์ ์ ํด๋์ค์ ์ ์ธํ๊ฒ ๋๋ฉด, ์ปจํธ๋กค๋ฌ ๋จ์์ ์ผ์ด๋๋ ๋ชจ๋ ์๋ฌ์ ๋ํด ์ ์ญ์ ์ธ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
ExceptionHandler๋ฅผ ์ฌ์ฉํ๋ฉด ์ ์ญ์ ์ผ๋ก ์ผ์ด๋๋ ์๋ฌ ์ค ํน์ ์๋ฌ ํด๋์ค์ ์ง์ ํ์ฌ ๋ก์ง์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
๐ค Controller์ @ExceptionHandler์ ControllerAdvice์ @ExceptionHandler ์ค ์ฐ์ ์์๊ฐ ๋์๊ฒ์ ๋ฌด์์ธ๊ฐ์?
Controller์ @ExceptionHandler๊ฐ ๋จผ์ ์
๋๋ค.
HandlerExceptionResolver๋ ์ปจํธ๋กค๋ฌ ์์
์ค ๋ฐ์ํ ์์ธ๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง ๊ฒฐ์ ํ๋ ์ ๋ต์
๋๋ค.
์์ ์ค๋ช
๋๋ฆฐ @ExceptionHandler ์ด๋
ธํ
์ด์
์ ํ์ฉํ์ฌ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ๊ณผ @ControllerAdvice ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ์ปค์คํ
ํ Exception ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ค์ผ๋ก์จ, Global Level์์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ HandlerExceptionResolver๋ฅผ ์ด์ฉํ ์์ธ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์
๋๋ค.
Dispatcher Servlet์ ๊ธฐ๋ณธ์ ์ผ๋ก 3๊ฐ์ HandlerExceptionResolver๊ฐ ๋ฑ๋ก ๋์ด์์ต๋๋ค.
- ExceptionHandlerExceptionResolver
- ResponseStatusExceptionResolver
- DefaultHandlerExceptionResolver
์์ผ๋ก Resolver๊ฐ ์คํ๋ฉ๋๋ค.
- ExceptionHandlerExceptionResolver
- ์์์ ์ฌ์ฉํ @ExceptionHandler ์ด๋ ธํ ์ด์ ์ ๋ํ Resolver ํด๋์ค์ ๋๋ค.
- ResponseStatusExceptionResolver
- ResponseStatusExceptionResolver๋ ์์ธ์ ๋ํ Http ์๋ต์ ์ค์ ํด ์ค ์ ์์ต๋๋ค. ํน์ ์์ธ๊ฐ ๋ฐ์ํ์์ ๋ , ๋จ์ํ 500 (internal-server-error) ๋์ ๋ ๊ตฌ์ฒด์ ์ธ ์๋ต ์ํ๊ฐ์ ์ ๋ฌ ํด ์ค ์ ์์ต๋๋ค.
//@ExceptionHandler ์ด๋ ธํ ์ด์ ๊ณผ ํจ๊ป ์ฌ์ฉํ ์ ์๋ค. //๊ตฌ์ฒด์ ์ธ ์๋ต ์ฝ๋๋ฅผ ์ค ๋ฟ ์๋๋ผ, ๊ฐ๋จํ ์ฌ์ ๋ ์ ๋ฌ ํ ์ ์๋ค. @ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "Permission Denied") @ExceptionHandler(value=DemoException.class) public String handleDemoException(DemoException e) { log.error(e.getMessage()); return "/error/403"; }
- DefaultHandlerExceptionResolver
- DispatcherServlet์ ๋ํดํธ๋ก ๋ฑ๋ก ๋ ์์ 2๊ฐ์ง HandlerExceptionResolver์์ ์์ธ์ฒ๋ฆฌ๋ฅผ ํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ, ๋ง์ง๋ง์ผ๋ก DefaultHandlerExceptionResolver์์ ์์ธ์ฒ๋ฆฌ๋ฅผ ํด์ค๋๋ค.
- DefaultHandlerExceptionResolver์์๋ ๋ด๋ถ์ ์ผ๋ก Spring ํ์ค ์์ธ์ฒ๋ฆฌ๋ฅผ ํด์ค๋๋ค. ๊ฐ ์ํฉ์ ๊ฑธ๋ง๋ ์๋ต ์ฝ๋๋ฅผ ๋ฆฌํดํด ์ฃผ๋ ์ญํ ์ ํฉ๋๋ค.
- Request URL์ ๋ง๋ Controller๋ฅผ ๋ชป์ฐพ๋ ๊ฒฝ์ฐ โ 404 Not Found
- Controller ๋ฉ์๋ ์คํ ์ค ์์ธ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ โ 500 Internal Server error
- Controller์ ํ๋ผ๋ฏธํฐ ํ์์ด ์๋ชป๋ ๊ฒฝ์ฐ โ 400 Bad Request
DisptatcherServlet ๋ฐ์์ ๋ฐ์ํ๋ ์์ธ๋ก HandlerExceptionResolver์ ์ฒ๋ฆฌ๋ฅผ ๋ฐ์ ์ ์์ต๋๋ค. ์ด๋ฌํ ์์ธ ์ฒ๋ฆฌ๋ Web Application ๋ ๋ฒจ์์ ์ฒ๋ฆฌ๋ฅผ ํด์ค์ผ ํฉ๋๋ค.
- web.xml์ error-page๋ฅผ ์ ๋ฑ๋กํด์ค์ ์๋ฌ๋ฅผ ์ฌ์ฉ์์๊ฒ ์๋ตํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
- Filter ๋ด๋ถ์์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ํํฐ๋ฅผ ๋ฐ๋ก ๋ฌ์ try-catch๋ฌธ์ ์ฌ์ฉํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค.
- Filter ๋ด๋ถ์์ try-catch ๊ตฌ๋ฌธ์ ํตํด ์์ธ ๋ฐ์ ์, HandlerExceptionResolver๋ฅผ ๋น์ผ๋ก ์ฃผ์
๋ฐ์ @ExceptionHandler์์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
์ฆ, ํํฐ์์ ๋ฐ์ํ๋ ์์ธ๋ฅผ ๋์คํจ์ฒ ์๋ธ๋ฆฟ์ ์์ธ ์ฒ๋ฆฌ์ธ HandlerExceptionResolver์ ๋ณด๋ด์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
ํํฐ๋ Servlet Filter๋ก์จ javax.servlet ์คํ์ ํฌํจ๋๋ ํด๋์ค์
๋๋ค.
์ธํฐ์
ํฐ๋ Spring MVC ์คํ์ ํฌํจ๋์ด ์๋ ํด๋์ค์
๋๋ค.
ํํฐ๋ Dispatcher Servlet์ ์์ฒญ์ด ์ ๋ฌ๋๊ธฐ ์ ๊ณผ ํ์ url ํจํด์ ๋ง๋ ๋ชจ๋ ์์ฒญ์ ๋ํด ๋ถ๊ฐ์์
์ ์ฒ๋ฆฌํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ค๋๋ค.
๋ฐ๋ฉด ์ธํฐ์
ํฐ๋ Spring์ด ์ ๊ณตํ๋ ๊ธฐ์ ๋ก์จ, Dispatcher Servlet์ด ์ปจํธ๋กค๋ฌ๋ฅผ ํธ์ถํ๊ธฐ ์ , ํ๋ก ๋ผ์ด๋ค๊ธฐ ๋๋ฌธ์ ์คํ๋ง์ ์์ญ ๋ด๋ถ์์ Controller(Handler)์ ๊ดํ ์์ฒญ๊ณผ ์๋ต์ ๋ํด ์ฒ๋ฆฌํด์ค๋๋ค.
๐ค Filter๋ Servlet์ ์คํ์ด๊ณ , Interceptor๋ Spring MVC์ ์คํ์
๋๋ค.
Spring Application์์ Filter์ Interceptor๋ฅผ ํตํด ์์ธ๋ฅผ ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
Interceptor๋ DispatcherServlet ๋ด๋ถ์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ HandlerExceptionResolver๋ฅผ ์ฌ์ฉํด์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ ์๊ฐ ์์ต๋๋ค.
ํ์ง๋ง, Filter๋ DispatcherServlet ์ธ๋ถ์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ์์ธ๊ฐ ๋ฐ์ํ์ ๋ Web Application ๋ ๋ฒจ์์ ์ฒ๋ฆฌํด์ฃผ์ด์ผ ํฉ๋๋ค.
๋ํ์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก๋ Filter ๋ด๋ถ์์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ํํฐ๋ฅผ ๋ฐ๋ก ๋ฌ์ try-catch๋ฌธ์ ์ฌ์ฉํ์ฌ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๋ ์๊ฐ ์์ต๋๋ค.
๋ํ, HandlerExceptionResolver๋ฅผ ๋น์ผ๋ก ์ฃผ์
๋ฐ์ @ExceptionHandler์์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
Filter์ Interceptor๋ ๊ณตํต ์ ๋ฌด๋ฅผ ํ๋ก๊ทธ๋จ ํ๋ฆ์ ์, ์ค๊ฐ, ๋ค์ ์ถ๊ฐํ์ฌ ์๋์ผ๋ก ์ฒ๋ฆฌํ ๋ ์ฌ์ฉํฉ๋๋ค.
์๋ฐ ์น ๊ฐ๋ฐ์ ํ๋ค๋ณด๋ฉด, ๊ณตํต์ ์ผ๋ก ์ฒ๋ฆฌํด์ผ ํ ์
๋ฌด๋ค์ด ๋ง์ต๋๋ค.
์๋ฅผ ๋ค์ด ๋ก๊ทธ์ธ ๊ด๋ จ(์ธ์
์ฒดํฌ)์ฒ๋ฆฌ, ๊ถํ ์ฒดํฌ, XSS(Cross site script)๋ฐฉ์ด, ํ์ด์ง ์ธ์ฝ๋ฉ ๋ณํ ๋ฑ์ด ์์ต๋๋ค.
๊ณตํต์
๋ฌด์ ๊ด๋ จ๋ ์ฝ๋๋ฅผ ๋ชจ๋ ํ์ด์ง ๋ง๋ค ์์ฑ ํด์ผํ๋ค๋ฉด ์ค๋ณต๋ ์ฝ๋๊ฐ ๋ง์์ง๊ฒ ๋๊ณ ํ๋ก์ ํธ ๋จ์๊ฐ ์ปค์ง์๋ก ์๋ฒ์ ๋ถํ๋ฅผ ์ค ์๋์์ผ๋ฉฐ, ์์ค ๊ด๋ฆฌ๋ ๋์ง ์์ต๋๋ค.
์ฆ, ๊ณตํต ๋ถ๋ถ์ ๋นผ์ ๋ฐ๋ก ๊ด๋ฆฌํ๋๊ฒ ์ข์ต๋๋ค.
์ด๋ฌํ ๊ณตํต์
๋ฌด๋ฅผ ํ๋ก๊ทธ๋จ ํ๋ฆ์ ์, ์ค๊ฐ, ๋ค์ ์ถ๊ฐํ์ฌ, ์๋์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด, Filter์ Interceptor๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค.
- Filter๋ ์ ์ฒด์ ์ธ Request๋จ์์ ์ด๋ค ์ฒ๋ฆฌ๊ฐ ํ์ํ ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ์ธ์ฆ, ์ด๋ฏธ์ง ๋ณํ, ๋ฐ์ดํฐ ์์ถ, ์ํธํ ํํฐ, XML ์ปจํ ์ธ ๋ฅผ ๋ณํํ๋ XSLT ํํฐ, URL ๋ฐ ๊ธฐํ์ ๋ณด๋ฅผ ์บ์ํ๋ ํํฐ, ๋ฌธ์ ์ธ์ฝ๋ฉ
- Interceptor๋ ์ธ์ ๋ฐ ์ฟ ํค ์ฒดํฌ์ ๊ฐ์ด http ํ๋กํ ์ฝ ๋จ์๋ก ์ฒ๋ฆฌํด์ผ ํ๋ ์ ๋ฌด๊ฐ ์์ ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.






