Skip to content

Latest commit

ย 

History

History
872 lines (631 loc) ยท 44.1 KB

File metadata and controls

872 lines (631 loc) ยท 44.1 KB

Spring Framework

๋ชฉ์ฐจ

Spring

  • 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๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?


ํ•ต์‹ฌ๋‹ต๋ณ€

POJO๋ž€, Plain Old Java Object์˜ ์•ฝ์ž๋กœ, ๋‹ค๋ฅธ ํด๋ž˜์Šค๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›์ง€ ์•Š์€, ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ๋งŒ ๊ฐ€์ง„ ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.
์ฆ‰, POJO๋Š” ๊ฐ์ฒด์ง€ํ–ฅ์  ์›๋ฆฌ์— ์ถฉ์‹คํ•˜๊ณ , ํŠน์ • ๊ทœ์•ฝ๊ณผ ํ™˜๊ฒฝ์— ์ข…์†๋˜์ง€ ์•Š๊ฒŒ ์žฌํ™œ์šฉ ๋  ์ˆ˜ ์žˆ๊ฒŒ ์„ค๊ณ„๋œ ๊ฐ์ฒด๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.
POJO๋ฅผ ์‚ฌ์šฉํ• ๋•Œ์˜ ์ด์ ์€, ์ข…์†๋œ ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•จ์œผ๋กœ ์ฝ”๋“œ์˜ ๊ฐ„๊ฒฐํ•ด์ง‘๋‹ˆ๋‹ค.
๋˜ํ•œ, ์ž๋™ํ™” ํ…Œ์ŠคํŠธ์˜ ์œ ๋ฆฌํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” Spring Framework์—์„œ POJO๋Š” ๋ฌด์—‡์ด ๋  ์ˆ˜ ์žˆ์„๊นŒ์š”?

Spring์€ ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ POJOํ”„๋ ˆ์ž„์›Œํฌ์ด๋ฉฐ, POJO๋ž€ ๊ฐ์ฒด์ง€ํ–ฅ์ ์ธ ์›๋ฆฌ์— ์ถฉ์‹คํ•œ ๋ฐฉ์‹์œผ๋กœ ์„ค๊ณ„๋œ ์ž๋ฐ” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.
Spring์—์„œ๋Š” ๋„๋ฉ”์ธ๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋Œ€์ƒ์ด POJO๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” 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 ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ์ฝ”๋“œ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.




Spring DI/IoC๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋‚˜์š”?


ํ•ต์‹ฌ๋‹ต๋ณ€

IoC(์ œ์–ด์˜ ์—ญ์ „)์€ main() ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ค์Œ ์‚ฌ์šฉ ๊ฐ์ฒด๋ฅผ ๊ฒฐ์ •, ์ƒ์„ฑ, ํ˜ธ์ถœํ•ด ๋‚˜๊ฐ€๋Š” ์ผ๋ฐ˜์ ์ธ ํ”„๋กœ๊ทธ๋žจ ํ๋ฆ„๊ณผ ๋‹ฌ๋ฆฌ ์™ธ๋ถ€์—์„œ ์ œ์–ด ํ๋ฆ„์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์Šคํ”„๋ง์—์„œ๋Š” IoC ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ๊ฐ์ฒด๊ฐ„์˜ ์˜์กด ๊ด€๊ณ„๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ , ๊ฐ์ฒด ๋ ˆํผ๋Ÿฐ์Šค๋„ ์ œ๊ณตํ•ด ์ค๋‹ˆ๋‹ค.

DI๋Š” ํด๋ž˜์Šค ๊ฐ„ ์ง์ ‘์ ์ธ ์˜์กด ๊ด€๊ณ„ ํ˜•์„ฑ์‹œ ๋ฐœ์ƒํ•˜๋Š” ๋†’์€ ๊ฒฐํ•ฉ๋„(coupling)๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด
interface์˜ ํ™œ์šฉ์„ ํ†ตํ•ด ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ์ฃผ์ž… ํ›„ setter๋‚˜ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”์–ด ์ฝ”๋“œ์˜ ์žฌํ™œ์šฉ์„ฑ์„ ๋†’์ด๊ณ  ์‚ฌ์šฉ์ž ์š”๊ตฌ์— ๋Œ€ํ•ด ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.




IoC ์ปจํ…Œ์ด๋„ˆ์˜ ์—ญํ• ์€ ๋ฌด์—‡์ด ์žˆ์„๊นŒ์š”?


ํ•ต์‹ฌ๋‹ต๋ณ€

์ปจํ…Œ์ด๋„ˆ๋Š” ๊ฐ์ฒด์˜ ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋“ค์—๊ฒŒ ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
์Šคํ”„๋ง์—์„œ๋Š” IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ํ•˜๊ณ , POJO์˜ ์ƒ์„ฑ, ์ดˆ๊ธฐํ™”, ์„œ๋น„์Šค, ์†Œ๋ฉธ์— ๋Œ€ํ•œ ๊ถŒํ•œ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœ์ž๋Š” ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•˜์—ฌ ๊ฐœ๋ฐœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.




Spring IoC/DI(์˜์กด์„ฑ ์ฃผ์ž…)์˜ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•„๋Š”๋Œ€๋กœ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.


ํ•ต์‹ฌ๋‹ต๋ณ€

  • ์ƒ์„ฑ์ž(Constructor Injection) ์ฃผ์ž…
  • ํ•„๋“œ(Field Injection) ์ฃผ์ž…
  • ์ˆ˜์ •์ž(Setter Injection) ์ฃผ์ž…



๊ฐ DI ์ฃผ์ž… ๋ฐฉ์‹์˜ ์ฐจ์ด์ ๊ณผ ์ด์ ์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.


ํ•ต์‹ฌ๋‹ต๋ณ€

์ˆ˜์ •์ž ์ฃผ์ž…(Setter Injection)์€ Setter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋Ÿฐํƒ€์ž„์‹œ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•ด ๋‚ฎ์€ ๊ฒฐํ•ฉ๋„๋ฅผ ๊ฐ–๋Š”๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์ง€๋งŒ, Setter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ฃผ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋„ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์–ด NullPointException์ด ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„๋“œ ์ฃผ์ž…(Field Injection)์€ ๋ณ€์ˆ˜ ์„ ์–ธ๋ถ€์— @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž๋™์œผ๋กœ ์˜์กด์„ฑ์ด ์ฃผ์ž…๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ„ํŽธํ•˜์ง€๋งŒ, ์ฐธ์กฐ ๊ด€๊ณ„๋ฅผ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•˜๊ธฐ ์–ด๋ ต๊ณ  ์ˆ˜์ •์ž ์ฃผ์ž…๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋Ÿฐํƒ€์ž„์‹œ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•ด NullPointerException์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ์„ฑ์ž ์ฃผ์ž…(Constructor Injection)์€ ์„ ์–ธ๋œ ์ƒ์„ฑ์ž๋ฅผ ์ด์šฉํ•ด ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ˆ˜์ •์ž ์ฃผ์ž…๊ณผ ํ•„๋“œ ์ฃผ์ž…๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์— ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์ง• ๋•๋ถ„์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™์‹œ์— ํ•ด๋‹น ์˜ค๋ฅ˜๋ฅผ ์žก์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.




์˜์กด์„ฑ๊ณผ ์„ค์ •๊ฐ’์„ ์ƒ์„ฑ์ž ์ธ์ž๋กœ ์ฃผ์ž…ํ•ด์•ผ ํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.


ํ•ต์‹ฌ๋‹ต๋ณ€

ํ•„๋“œ ์ฃผ์ž…๊ณผ ์ˆ˜์ •์ž ์ฃผ์ž…์˜ ๊ฒฝ์šฐ ๋นˆ์ด ์ƒ์„ฑ๋œ ํ›„์— ์ฐธ์กฐ๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋Ÿฐํƒ€์ž„ ์‹œ๊นŒ์ง€ ์˜ค๋ฅ˜๋‚˜ ๊ฒฝ๊ณ  ์—†์ด ๊ตฌ๋™๋˜์ง€๋งŒ, ์ƒ์„ฑ์ž ์ฃผ์ž…์˜ ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™ ์‹œ์— ์ˆœํ™˜ ์ฐธ์กฐ์— ๋Œ€ํ•œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด ์„œ๋ฒ„ ๊ตฌ๋™์— ์žˆ์–ด ํฌ๋ฆฌํ‹ฐ์ปฌํ•œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋กœ ์Šคํ”„๋ง ๋ ˆํผ๋Ÿฐ์Šค์—์„œ๋„ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๋ญ์ฃ ?

Bean A โ†’ Bean B โ†’ Bean A ์ฒ˜๋Ÿผ, ๋นˆ๋“ค์ด ์„œ๋กœ ๊ณ„์† ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ปจํ…Œ์ด๋„ˆ๋Š” ์–ด๋А ๋นˆ์„ ๋จผ์ € ์ƒ์„ฑํ•ด์•ผํ•˜๋Š”์ง€ ํŒ๋‹จํ•˜์ง€ ๋ชปํ•˜๊ณ  ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.




MVC ํŒจํ„ด์ด๋ž€?


ํ•ต์‹ฌ๋‹ต๋ณ€

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ 3๊ฐ€์ง€ ์—ญํ• ๋กœ ๊ตฌ๋ถ„ํ•œ ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•๋ก ์ž…๋‹ˆ๋‹ค.

  1. Model: ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰ ๋ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ
  2. View: Model์ด ์ฒ˜๋ฆฌํ•œ ๋ฐ์ดํ„ฐ์˜ ์‹œ๊ฐํ™” = ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ํ™”๋ฉด
  3. Controller: Model๊ณผ View์˜ ์‚ฌ์ด ์—ฐ๊ฒฐ ๋ฐ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ์ œ์–ด

๐Ÿค” MVC ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

์—ญํ• ์„ 3๊ฐ€์ง€(์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๋Š” ํŽ˜์ด์ง€, ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ, ์ด๋ฅผ ์ค‘๊ฐ„์—์„œ ์ œ์–ดํ•˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ)๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋‹ด๋‹นํ•จ์œผ๋กœ์จ ์ƒ๊ธฐ๋Š” ์ด์ ์ด ๋งŽ์Šต๋‹ˆ๋‹ค.

  1. ์ฝ”๋“œ ์ˆ˜์ •์ด ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.
    • ์œ ์ง€๋ณด์ˆ˜ ๋˜๋Š” ํ™•์žฅ์„ฑ ๋ณด์žฅ
  2. ๊ฒฐํ•ฉ๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    1. ๊ด€๋ จ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ํ•˜๋‚˜์˜ Controller๋กœ ๋ฌถ๊ฑฐ๋‚˜, ํŠน์ • Model๊ณผ ๊ด€๋ จ ์žˆ๋Š” View ๊ทธ๋ฃนํ™”๊ฐ€ ๊ฐ€๋Šฅ
    2. ๋‹จ, ํ•˜๋‚˜์˜ Controller์— ๋‹ค์ˆ˜์˜ Model๊ณผ View๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์–ด, ์„œ๋กœ์˜ ์˜์กด์„ฑ ๋ฌธ์ œ ๋ฐœ์ƒ ๊ฐ€๋Šฅ

๐Ÿค” MVC ํŒจํ„ด์˜ ๋™์ž‘ ๊ณผ์ •์€ ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”?

์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ์„ ๋‹ด๋‹นํ•˜๋Š” View๋ฅผ ํ†ตํ•ด ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ํ•ด๋‹น ์š”์ฒญ์„ Controller๊ฐ€ ๋ฐ›๊ณ ,
Controller๋Š” Model์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ถœ๋ ฅ์„ ๋‹ด๋‹นํ•˜๋Š” View๋ฅผ ์ œ์–ดํ•ด์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” Model, View, Controller ์ž์„ธํžˆ

Model
  • Model์ด๋ž€?
    • ๋„๋ฉ”์ธ ๊ฐ์ฒด ๋˜๋Š” DTO๋กœ ํ™”๋ฉด์— ์ „๋‹ฌํ•  ๋˜๋Š” ํ™”๋ฉด์—์„œ ์ „๋‹ฌ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๊ฐ์ฒด
    • Model์˜ ์ƒํƒœ์— ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ ์ปจํŠธ๋กค๋Ÿฌ์™€ View์— ์ด๋ฅผ ํ†ต๋ณดํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๋ฐ˜๋Œ€๋กœ Controller์™€ View๊ฐ€ ์ง์ ‘ Model์˜ ์ƒํƒœ๋ฅผ ์ฝ์–ด์˜ค๊ธฐ๋„ ํ•œ๋‹ค.
    • Model์€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์•„๋„ ๋˜๊ณ , ์ˆœ์ˆ˜ํ•˜๊ฒŒ public ํ•จ์ˆ˜๋กœ๋งŒ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. (POJO)
  • ๊ตฌ์„ฑ ์š”์†Œ
    • Service : DB ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ์™€ ๋„๋ฉ”์ธ์—๊ฒŒ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„
    • ๋„๋ฉ”์ธ ๊ฐ์ฒด : ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰
    • DAO(or Repository) : DB CRUD
    • DTO : Layer๊ฐ„ ํ†ต์‹ ์šฉ
Controller
  • Controller๋ž€?
    • ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ๋ฐ›์•„ Model ๊ฐ์ฒด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜, Model ๊ฐ์ฒด๋ฅผ View์— ์ „๋‹ฌํ•˜๋Š” ์—ญํ• 
    • ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ฐ›์•˜์„ ๋•Œ ๊ทธ ์š”์ฒญ์— ๋Œ€ํ•ด ์‹ค์ œ ์—…๋ฌด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” Model ์ปดํฌ๋„ŒํŠธ ํ˜ธ์ถœ
    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋ฉด, Model ํ˜ธ์ถœ ์‹œ ์ „๋‹ฌํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ ์ ˆํžˆ ๊ฐ€๊ณต
    • Model์ด ์—…๋ฌด ์ˆ˜ํ–‰์„ ์™„๋ฃŒํ•˜๋ฉด, ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ง€๊ณ  ํ™”๋ฉด์„ ์ƒ์„ฑํ•˜๋„๋ก View์— ์ „๋‹ฌํ•œ๋‹ค.
  • ์ฑ…์ž„
    • ์ž…๋ ฅ๊ฐ’ ๊ฒ€์ฆ
    • ์ž…๋ ฅ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋กœ Model ๊ฐ์ฒด ๋ณ€๊ฒฝ
    • ๋ณ€๊ฒฝ๋œ Model ๊ฐ์ฒด๋ฅผ View์— ์ „๋‹ฌ
    • Service Layer์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌ ์š”์ฒญ โ†’ Service๋Š” ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌ ํ›„ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
View
  • View๋ž€?
    • ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• 
    • ๋‹ค์–‘ํ•œ ํ˜•ํƒœ๋กœ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋‹ค.
  • ์˜ˆ์‹œ
    • HTML, JSON, XML, JSP, Thymleaf ๋“ฑ



ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?


ํ•ต์‹ฌ๋‹ต๋ณ€

Front Controller ํŒจํ„ด์ด๋ž€ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํ•˜๋‚˜๊ฐ€ ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ์˜ ์ œ์ผ ์•ž์—์„œ ์„œ๋ฒ„๋กœ ๋“ค์–ด์˜ค๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ๋ชจ๋“  ์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋””์ž์ธํ•œ ํŒจํ„ด์ž…๋‹ˆ๋‹ค.


๐Ÿค” ์Šคํ”„๋ง MVC ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ• ๊นŒ?

  • ๊ตฌ์กฐ ๋น„๊ต

    1. ๊ธฐ์กด ํŒจํ„ด
    • ๊ฐ ํด๋ผ์ด์–ธํŠธ๋“ค์€ Controller A, B, C์— ๋Œ€ํ•ด ๊ฐ๊ฐ ํ˜ธ์ถœํ•œ๋‹ค.
    • ๊ณตํ†ต ์ฝ”๋“œ๋“ค์€ ๋ณ„๋„๋กœ ์ฒ˜๋ฆฌ๋˜์–ด ์žˆ์ง€ ์•Š๊ณ  ๊ฐ Controller์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.
    • ๋‹จ์ :
      • ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ๋งค๋ฒˆ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ์„ ๋‹ค๋ค„์•ผ ํ•œ๋‹ค๋Š” ์–ด๋ ค์›€์ด ์žˆ๋‹ค. (๊ด€๋ฆฌ์˜ ์ธก๋ฉด)
      • ํ•ธ๋“ค๋Ÿฌ์˜ ๊ณตํ†ต ๋กœ์ง์ด ๋งค๋ฒˆ ์ค‘๋ณต๋œ๋‹ค. (๊ฐœ๋ฐœ์˜ ์ธก๋ฉด)

    https://user-images.githubusercontent.com/90819869/153976572-3eb68212-1225-4e1b-b430-ab4b2e1e03b5.png

    1. Front Controller(๋Œ€ํ‘œ ์ปจํŠธ๋กค๋Ÿฌ) ํŒจํ„ด
    • ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๊ฒฝ์šฐ, Front Controller๊ฐ€ ๊ฐ ์š”์ฒญ์— ๋งž๋Š” ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฐพ์•„์„œ ํ˜ธ์ถœํ•œ๋‹ค.

    • ๊ณตํ†ต ์ฝ”๋“œ์— ๋Œ€ํ•ด์„œ๋Š” Front Controller์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ , ์„œ๋กœ ๋‹ค๋ฅธ ์ฝ”๋“œ๋“ค๋งŒ ๊ฐ Controller์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

    • View์—์„œ ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ์š”์ฒญ์„ ๋‹ด๋‹นํ•˜์—ฌ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๋Š” ๋ชจ๋“  ์š”์ฒญ์„ ์ผ๊ด„์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

      https://user-images.githubusercontent.com/90819869/153976771-7c6dad1f-480b-4883-82a0-d411f654f785.png

    • ์žฅ์ 

      • ๊ณตํ†ต๋œ ๋ถ€๋ถ„์„ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” FrontController๋กœ ์ค‘๋ณต์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
      • Front Controller ์™ธ์— ๋‹ค๋ฅธ Controller์—์„œ Servlet์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

๐Ÿค” Spring Web MVC์—์„œ ์š”์ฒญ๋งˆ๋‹ค Thread๊ฐ€ ์ƒ์„ฑ๋˜์–ด Controller๋ฅผ ํ†ตํ•ด ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ• ํ…๋ฐ, ์–ด๋–ป๊ฒŒ 1๊ฐœ์˜ Controller๋งŒ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ์„๊นŒ์š”?

Controller ๊ฐ์ฒด ํ•˜๋‚˜๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ๊ฐ์ฒด ์ž์ฒด๋Š” Heap์— ์ƒ์„ฑ๋˜์ง€๋งŒ, ํ•ด๋‹น Class์˜ ์ •๋ณด๋Š” ๋ฉ”์†Œ๋“œ ์˜์—ญ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
๋ชจ๋“  Thread๋Š” ๊ฐ์ฒด์˜ Binary Code ์ •๋ณด๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ณต์œ ๋˜๋Š” ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๊ตณ์ด Controller ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์“ฐ๋ ˆ๋“œ๋‚˜ Controller ๊ฐ์ฒด ์ž์ฒด๊ฐ€ Block๋  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
์™œ๋ƒํ•˜๋ฉด, ๊ฐ์ฒด ๋‚ด๋ถ€์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ์—†์œผ๋‹ˆ, ๋‚ด๋ถ€์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ผ์ด ์—†๊ณ  ๊ทธ์ € ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋งŒ โ€˜๊ฐ™์ด ๊ณต์œ ํ•ด์„œโ€™ ์“ฐ๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
Controller๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ์—†์œผ๋‹ˆ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ๋งŒ ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตณ์ด ๋™๊ธฐํ™”ํ•  ์ด์œ ๊ฐ€ ์—†๊ณ , ๊ทธ์ € ์ฒ˜๋ฆฌ ๋กœ์ง๋งŒ โ€˜๊ณต์œ ๋˜์–ดโ€™ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ช‡ ์‹ญ๋งŒ๊ฐœ์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋“  ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค.




Spring Web MVC์˜ Dispatcher Servlet์˜ ๋™์ž‘ ์›๋ฆฌ์— ๋Œ€ํ•ด์„œ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.


ํ•ต์‹ฌ๋‹ต๋ณ€

Dispatcher Servlet์€ ๋ชจ๋“  ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ์ž…๋‹ˆ๋‹ค.
Spring Web MVC์˜ Dispatcher Servlet์˜ ๋™์ž‘ ์›๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ๋ธŒ๋ผ์šฐ์ €์˜ ๋ชจ๋“  ์š”์ฒญ์ด Dispatcher Servlet์—๊ฒŒ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.
  2. Dispatcher Servlert์ด ์š”์ฒญ์„ ๋ฐ›์œผ๋ฉด ๊ทธ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” Hanlder์˜ ์ด๋ฆ„์„ Handler Mapping ์—๊ฒŒ ๋ฌผ์–ด๋ด…๋‹ˆ๋‹ค.
  3. Handler Mapping์€ ์š”์ฒญ URL์„ ๋ณด๊ณ  Handler๋ฅผ ํŒ๋‹จํ•˜๊ณ  Handler Name์„ ๊ณผ ํ•จ๊ป˜ ์ œ์–ด๊ถŒ์„ Dispacher Servlet์—๊ฒŒ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.
  4. Handler ์‹คํ–‰ ์ „์— ์ „์ฒ˜๋ฆฌ, ํ›„์ฒ˜๋ฆฌ๋กœ ์‹คํ–‰ํ•ด์•ผํ•  ์ธํ„ฐ์…‰ํ„ฐ ๋ชฉ๋ก์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
  5. Service์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  6. Handler๋Š” ๋žœ๋”๋งํ•ด์•ผํ•˜๋Š” View Name์„ ํŒ๋‹จํ•ด์„œ Dispatcher Servlet์— ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
  7. Dispatcher Servlet์€ View name์„ View Resolver์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  8. View Resolver๋Š” ์ „๋‹ฌ๋ฐ›์€ ๊ฐ’์œผ๋กœ ์ ์ ˆํ•œ View๋ฅผ ์ƒ์„ฑํ•˜์—ฌ Dispatcher Servlet์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  9. Dispatcher Servlet์€ View์— Model๊ณผ Controller๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  10. View๋กœ ๋ถ€ํ„ฐ ๋ฐ›์€ ์‘๋‹ต์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” ์ธํ„ฐ์…‰ํ„ฐ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

์Šคํ”„๋ง MVC ๋ชจ๋“ˆ์—์„œ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ด์šฉํ•ด์„œ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์ „ ํ˜น์€ ํ›„์— ๋Œ€ํ•œ ๋กœ์ง์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Œ์œผ๋กœ ์ฃผ๋กœ ํŠน์ • ์š”์ฒญ์— ๋Œ€ํ•œ ๊ณตํ†ต ๋กœ์ง ์ ์šฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” DispatcherServlet ๊ตฌ์„ฑ ์š”์†Œ

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(Aspect Oriented Programming)๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”?

AOP๋ž€ Aspect Oriented Programming, ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
๊ด€์ ์ง€ํ–ฅ์ด๋ž€, ์–ด๋–ค ๋กœ์ง์„ ๊ธฐ์ค€์œผ๋กœ ํ•ต์‹ฌ์ ์ธ ๊ด€์ , ๋ถ€๊ฐ€์ ์ธ ๊ด€์ ์œผ๋กœ ๋‚˜๋ˆ„์–ด์„œ ๊ฐ๊ฐ ๋ชจ๋“ˆํ™”ํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ AOP๋Š” ํ•ต์‹ฌ๊ธฐ๋Šฅ๊ณผ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋‚˜๋ˆ„์–ด์„œ ์„ค๊ณ„, ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.


๐Ÿค” AOP ๊ธฐ์ˆ ์„ ์ ์šฉํ•˜๋Š” ์ด์œ ๊ฐ€ ๋ญ”๊ฐ€์š”?

ํ•„์ˆ˜์ ์ด์ง€๋งŒ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ฝ”๋“œ, log ์ถœ๋ ฅ์ด๋‚˜, ์˜ˆ์™ธ์ฒ˜๋ฆฌ ๊ฐ™์€ ๋ถ€๋ถ„์„ ๋ชจ๋“ˆํ™” ์‹œ์ผœ, ๋ฆฌํŒฉํ† ๋ง๊ณผ ์œ ์ง€๋ณด์ˆ˜์— ์ด์ ์„ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
์Šคํ”„๋ง์—์„œ AOP๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, ๊ฐœ๋ฐœ ์ฝ”๋“œ์—์„œ๋Š” ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ณ , ๋Ÿฐํƒ€์ž„ ์‹คํ–‰ ์‹œ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง ์•ž๊ณผ, ๋’ค ์›ํ•˜๋Š” ์ง€์ ์—์„œ ๊ณตํ†ต ๊ด€์‹ฌ์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ํ•˜์—ฌ ์ค‘๋ณต์ฝ”๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” AOP๊ฐ€ ์ ์šฉ๋˜๋Š” ์œ„์น˜๋Š” ์–ด๋–ป๊ฒŒ ์ œ์–ดํ•˜๋‚˜์š”?

์Šคํ”„๋ง AOP์—์„œ๋Š” Advice๊ฐ€ ์ ์šฉ๋˜๋Š” 5๊ฐ€์ง€ ์‹œ์ ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  1. @Around() : ์ฒซ๋ฒˆ์งธ๋กœ, Around() ์–ด๋…ธํ…Œ์ด์…˜์€ ํ•ต์‹ฌ๊ธฐ๋Šฅ ์ „๊ณผ ํ›„ ๋ชจ๋‘ ์‹คํ–‰๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  2. @Before() : Before() ์–ด๋…ธํ…Œ์ด์…˜์€ ํ•ต์‹ฌ๊ธฐ๋Šฅ ํ˜ธ์ถœ์ „์— ์‹คํ–‰๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  3. @After() : ์„ธ๋ฒˆ์งธ๋กœ, After() ์–ด๋…ธํ…Œ์ด์…˜์€ 'ํ•ต์‹ฌ๊ธฐ๋Šฅ'์˜ ์ˆ˜ํ–‰ ์„ฑ๊ณต ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ์ˆ˜ํ–‰ ํ›„ ์–ธ์ œ๋‚˜ ์‹คํ–‰๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  4. @AfterReturning() : AfterReturning()์€ 'ํ•ต์‹ฌ๊ธฐ๋Šฅ'์˜ ํ˜ธ์ถœ ์„ฑ๊ณต์‹œ์—๋งŒ ์‹คํ–‰๋  ๊ฒƒ์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  5. @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;
	}

}

๐Ÿค” AOP์˜ ํŠน์ง•์— ๋Œ€ํ•ด์„œ ์„ค๋ช…๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

  • ํ”„๋ก์‹œ ํŒจํ„ด ๊ธฐ๋ฐ˜์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ ‘๊ทผ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ํ”„๋ก์‹œ๊ฐ€ ํ˜ธ์ถœ์„ ์ธํ„ฐ์…‰ํ„ฐํ•ด์„œ ํ•ต์‹ฌ ๋กœ์ง ์ „๊ณผ ํ›„์— ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ•ต์‹ฌ ๊ธฐ๋Šฅ์˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๋Ÿฐํƒ€์ž„ ์‹œ์ ์—๋งŒ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” ํ”„๋ก์‹œ ํŒจํ„ด์ด๋ž€?

์–ด๋–ค ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œ์–ดํ•˜๊ฑฐ๋‚˜ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์šฉ๋„๋กœ ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ๋Œ€์‹ ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

๐Ÿค” ํ”„๋ก์‹œ ํŒจํ„ด ๋™์ž‘ ์›๋ฆฌ์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์œผ๋กœ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๊ณ , ํ”„๋ก์‹œ๋Š” ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ๊ฐ–๋Š” ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ๊ฐ์‹ธ์„œ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ํŠน์ง• ๋•๋ถ„์— ํ”„๋ก์‹œ ํŒจํ„ด์€ ์ ‘๊ทผ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ณ  ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๐Ÿค” AOP์˜ ์ฃผ์š” ๊ฐœ๋…๋“ค์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”

  • Aspect : ํฉ์–ด์ง„ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ชจ๋“ˆํ™” ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋ชจ๋“ˆํ™”ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • Target : Aspect๋ฅผ ์ ์šฉํ•˜๋Š” ๊ณณ์šธ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. Target์€ ์ฃผ๋กœ ํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ ๋“ฑ์ด ๋ฉ๋‹ˆ๋‹ค.
  • Advice : ์‹ค์งˆ์ ์œผ๋กœ ์–ด๋–ค ์ผ์„ ํ•ด์•ผํ•  ์ง€์— ๋Œ€ํ•œ ๊ฒƒ์„ ์˜๋ฏธํ•˜๋นˆ๋‹ค.Advice๋Š” ์‹ค์งˆ์ ์ธ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋‹ด์€ ๊ตฌํ˜„์ฒด์ž…๋‹ˆ๋‹ค.
  • JoinPoint : Advice๊ฐ€ ์ ์šฉ๋  ์œ„์น˜, ๋ผ์–ด๋“ค ์ˆ˜ ์žˆ๋Š” ์ง€์ , ๋ฉ”์„œ๋“œ ์ง„์ž… ์ง€์ , ์ƒ์„ฑ์ž ํ˜ธ์ถœ ์‹œ์ , ํ•„๋“œ์—์„œ ๊ฐ’์„ ๊บผ๋‚ด์˜ฌ ๋•Œ์˜ ์‹œ์ ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ์•ฑ์„ ์‹คํ–‰ํ•  ๋•Œ ํŠน์ • ์ž‘์—…์ด ์‹œ์ž‘๋˜๋Š” ์‹œ์ ์ž…๋‹ˆ๋‹ค.
  • PointCut : JoinPoint๊ฐ€ ์ ์šฉ๋˜๋Š” ๋Œ€์ƒ, Adivice๊ฐ€ ์‹คํ–‰๋  ์ง€์ ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.



Spring์—์„œ CORS ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.


ํ•ต์‹ฌ๋‹ต๋ณ€

  • ์ฒซ ๋ฒˆ์งธ๋กœ, Servlet Filter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปค์Šคํ…€ํ•œ CORS ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋‘ ๋ฒˆ์งธ๋กœ, Controller ํด๋ž˜์Šค์— @Crossorigin ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„ธ ๋ฒˆ์งธ๋กœ,WebMvcConfiguer๋ฅผ ๊ตฌํ˜„ํ•œ Configuration ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ addCorsMappings()๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋งˆ์ง€๋ง‰์œผ๋กœ, Spring Security์—์„œ CorsConfigurationSource๋ฅผ Bean์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  config์— ์ถ”๊ฐ€ํ•ด์คŒ์œผ๋กœ์จ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” CORS์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ์ด์œ ๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€์š”?

CORS(Cross-Origin-Resource-Sharing)๋Š” Origin์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ(Cross-Oirgin) ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์›น๋ธŒ๋ผ์šฐ์ €๋Š” ์›๋ž˜ ๋™์ผ ์ถœ์ฒ˜ ์›์น™(Same Origin Policy)๋ฅผ ๋ณด์•ˆ์ƒ ๊ธฐ๋ณธ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ CORS์—๋Ÿฌ๋Š”, ๋™์ผํ•œ ์ถœ์ฒ˜์˜ Origin, ์ฆ‰ ์Šคํ‚ค๋งˆ, Host, Port๊ฐ€ ๊ฐ™์•„์•ผ๋งŒ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ณด์•ˆ ์ •์ฑ… ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” CORS ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”

1๏ธโƒฃ Servlet Filter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปค์Šคํ…€ํ•œ CORS ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•

์„œ๋ฒ„์˜ ์‘๋‹ต์„ ๋ณด๋‚ด๊ธฐ ์ „์— Access-Control-Allow-Origin ํ—ค๋”๋ฅผ ์‹ฃ๋Š” ํ•„ํ„ฐ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

  1. ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋œ CorsFilter ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ํ•ด๋‹น ํด๋ž˜์Šค์— 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() {

    }
}

2๏ธโƒฃ Controller ํด๋ž˜์Šค์— @Crossorigin ์–ด๋…ธํ…Œ์ด์…˜์„ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

  • 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);
    }
}

3๏ธโƒฃ WebMvcConfig๋ฅผ ๊ตฌํ˜„ํ•œ Configuration ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

  • 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");
    }
}



Bean์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด๋ณด์„ธ์š”.


ํ•ต์‹ฌ๋‹ต๋ณ€

Java Bean์€ ๋ฐ์ดํ„ฐ ํ‘œํ˜„์„ ๋ชฉ์ ์œผ๋กœ Java๋กœ ์ž‘์„ฑ๋œ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
private์œผ๋กœ ํ•„๋“œ๋ฅผ ์„ ์–ธํ•˜๊ณ  ์ „๋‹ฌ ์ธ์ž๊ฐ€ ์—†๋Š” ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. getter์™€ setter๋กœ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์ธ Properties๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” Spring Bean์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Spring IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ธ์Šคํ„ด์Šคํ™”, ๊ด€๋ฆฌ, ์ƒ์„ฑํ•˜๋Š” ์ž๋ฐ” ๊ฐ์ฒด์ด๋ฉฐ ApplicationContext๊ฐ€ ๋งŒ๋“ค์–ด์„œ ๊ทธ ์•ˆ์— ๋‹ด๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๊ธฐ์กด ์ž๋ฐ” ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ฒ˜๋Ÿผ Class ์ƒ์„ฑ ํ›„ new ์—ฐ์‚ฐ์ž๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ
ApplicationContext.getBean()์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์Šคํ”„๋ง์œผ๋กœ๋ถ€ํ„ฐ ๊ฐ์ฒด๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.

๐Ÿค” ์Šคํ”„๋ง Bean์˜ ์ƒ์„ฑ ๊ณผ์ •์„ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.

๊ฐ์ฒด ์ƒ์„ฑ โ†’ ์˜์กด ์„ค์ • โ†’ ์ดˆ๊ธฐํ™” โ†’ ์‚ฌ์šฉ โ†’ ์†Œ๋ฉธ ์ˆœ์„œ๋กœ ๋ผ์ดํ”„ ์‚ฌ์ดํด์„ ์ง€๋‹™๋‹ˆ๋‹ค.
1.์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ดˆ๊ธฐํ™” ๋  ๋•Œ ๋จผ์ € Bean ๊ฐ์ฒด๋ฅผ ์„ค์ • ์ •๋ณด์— ๋งž์ถฐ ํƒ์ƒ‰, ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
2.Bean์œผ๋กœ ๋“ฑ๋กํ•  ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๊ณ  ์˜์กด ๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.
3.ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด Bean ๊ฐ์ฒด๊ฐ€ ์ง€์ •ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ดˆ๊ธฐํ™” ํ•ฉ๋‹ˆ๋‹ค.
4.๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ ๋’ค ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ Bean์ด ์ง€์ •ํ•œ ๋ฉ”์„œ๋“œ(destroy method)๋ฅผ ํ˜ธ์ถœํ•ด ์†Œ๋ฉธํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” ์Šคํ”„๋ง Bean์˜ Scope์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.

Scope๋ž€ Bean์ด ์กด์žฌํ•˜๊ณ  ๊ด€๋ฆฌ๋˜๋Š” ๋ฒ”์œ„๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ Sington Scope๋กœ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, Singleton์€ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์‹œ์ž‘๊ณผ ์ข…๋ฃŒ๊นŒ์ง€ ๊ฐ€์žฅ ๋„“์€ ๋ฒ”์œ„๋กœ ํ•œ ๊ฐ์ฒด๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™ ์‹œ JVM ์•ˆ์—์„œ Spring์ด Bean๋งˆ๋‹ค ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฏ€๋กœ ๊ฐœ๋ฐœ์ž๋“ค์€ Spring์„ ํ†ตํ•ด Bean์„ ์ œ๊ณต๋ฐ›์œผ๋ฉด ์–ธ์ œ๋‚˜ ์ฃผ์ž…๋ฐ›์€ Bean์€ ๋™์ผํ•œ ๊ฐ์ฒด๋ผ๋Š” ๊ฐ€์ •ํ•˜์—์„œ ์ถœ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด, ProtoType Scope๋Š” Bean์˜ ์ƒ์„ฑ๊ณผ ์˜์กด ์„ค์ •๊นŒ์ง€๋งŒ ๊ด€์—ฌํ•˜๋Š” ๋งค์šฐ ์งง์€ ์Šค์ฝ”ํ”„์ž…๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ๋ชจ๋“  ์š”์ฒญ์—์„œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

1.singleton : ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์‹œ์ž‘๊ณผ ์ข…๋ฃŒ๊นŒ์ง€ ๋‹จ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹

https://user-images.githubusercontent.com/90819869/154178392-70e96c18-6a96-4b26-9ec9-8430aa7f491b.png

  1. prototype : ๋ชจ๋“  ์š”์ฒญ์—์„œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹

https://user-images.githubusercontent.com/90819869/154178422-3304cff2-d566-482f-b191-68c10613fc3f.png

๐Ÿค” Bean/Component ์–ด๋…ธํ…Œ์ด์…˜์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•ด์ฃผ์‹œ๊ณ , ๋‘˜์˜ ์ฐจ์ด์ ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.

  1. @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;
      }
  2. @Component

    ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์ž‘์„ฑํ•ด ์ปจํŠธ๋กค ํ•  ์ˆ˜ ์žˆ๋Š” Class๋ฅผ Bean์œผ๋กœ ๋“ฑ๋กํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    @Component(value="mybean")
    public class Example {
      puiblic Example(){
          System.out.println("Hello world");
        }
    }



Getter์™€ Setter๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.


ํ•ต์‹ฌ๋‹ต๋ณ€

  • ๊ฐ์ฒด์˜ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ๋ฅผ ๋“ค์–ด, ๋งŒ์•ฝ ์™ธ๋ถ€์—์„œ ๋ชธ๋ฌด๊ฒŒ๋ผ๋Š” ํ•„๋“œ์— ์ง์ ‘ ์ ‘๊ทผํ•œ๋‹ค๋ฉด 0๋ณด๋‹ค ๋‚ฎ์€ ๊ฐ’์„ ์ค„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๊ฐ์ฒด์˜ ๋ฌด๊ฒฐ์„ฑ์ด ๊นจ์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด Getter/Setter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ๋ฌด๊ฒฐ์„ฑ์„ ์ง€์ผœ์ค๋‹ˆ๋‹ค.

๐Ÿค” ๋ฌด๊ฒฐ์„ฑ์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

๋ฐ์ดํ„ฐ์˜ ์ •ํ™•์„ฑ๊ณผ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ๋ณด์ฆํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค”ย Getter/Setter๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์™œ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์ด ์ง€์ผœ์ง€๋‚˜์š”?

Getter, Setter๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑ ๋ฐ ์ ‘๊ทผ์„ ํ•˜๊ฒŒ ๋˜๋ฉด ๋“ค์–ด์˜ค๋Š” ๊ฐ’์„ ๋ฐ”๋กœ ์ €์žฅํ•˜๋Š” ๊ฒŒ ์•„๋‹Œ,
ํ•œ๋ฒˆ ๊ฒ€์ฆํ•˜๊ณ  ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ์˜ ๋ฌด๊ฒฐ์„ฑ์ด ์ง€์ผœ์ง‘๋‹ˆ๋‹ค.

  • Getterย : ๋ณธ ํ•„๋“œ์˜ ๊ฐ’์„ ์ˆจ๊ธด ์ฑ„ ๋‚ด๋ถ€์—์„œ ๊ฐ€๊ณต๋œ ๊ฐ’์„ ๊บผ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.
  • Setterย : ํ•„๋“œ๋ฅผ private๋กœ ๋งŒ๋“ค์–ด ์™ธ๋ถ€์˜ ์ ‘๊ทผ์„ ์ œํ•œํ•œ ํ›„, Setter๋ฅผ ์‚ฌ์šฉํ•ด ์ „๋‹ฌ๋ฐ›์€ ๊ฐ’์„ ๋‚ด๋ถ€์—์„œ ๊ฐ€๊ณตํ•ด ํ•„๋“œ์— ๋„ฃ์–ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿค” Getter/Setter๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์˜ ๋‹ค๋ฅธ ์ด์ ์€ ์—†๋‚˜์š”?

  1. Getter, Setter์™€ ๊ฐ™์€ ์—‘์„ธ์Šค ํ•จ์ˆ˜ ์‚ฌ์šฉ ์‹œ, ์œ„์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ๊ณผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ฐ์ฒด์˜ ํ•„๋“œ๋ฅผ private๊ณผ ๊ฐ™์€ ์ ‘๊ทผ์ œํ•œ์ž๋ฅผ ๋‘๋ฉด์„œ ๊ฐ์ฒด์ง€ํ–ฅ์˜ ๋ชฉ์ ์ธ ์ •๋ณด์€๋‹‰์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.



DTO๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ?


ํ•ต์‹ฌ๋‹ต๋ณ€

  • ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ์•„์„œ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์–ด ํ†ต์‹  ํšŸ์ˆ˜๋ฅผ ๊ฐ์†Œ์‹œํ‚ค๊ณ , ๊ฒ€์ฆ๊ณผ ๋กœ์ง ์ฒ˜๋ฆฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์™ธ๋ถ€์™€ ํ†ต์‹ ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์—๊ฒŒ ์žˆ์–ด ํ˜ธ์ถœ์€ ํฐ ๋น„์šฉ์ด๋ฉฐ, ์ด๋ฅผ ์ค„์ด๊ณ  ๋”์šฑ ํšจ์œจ์ ์œผ๋กœ ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ์•„ ํ•œ ๋ฒˆ์— ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ณ ์•ˆ๋˜์—ˆ๋Š”๋ฐ, ์ด ๋•Œ ์ด ํด๋ž˜์Šค๋ฅผ DTO๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฅผ ๋ฌถ์–ด ๋ณด๋‚ด๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ •์„ฑ์ด ๋†’๊ณ , ์ˆ˜ํ–‰์‹œ๊ฐ„์€ ๊ฐ์†Œ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ’ก ๋ณด์ถฉ์ง€์‹

DTO๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ์ž๋ฐ” Domain ๊ฐ์ฒด(๋ฐ์ดํ„ฐ)์— ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•˜์ง€ ์•Š์Œ์œผ๋กœ์จ, ์•„๋ž˜์™€ ๊ฐ™์€ ํŽธ๋ฆฌํ•จ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

โ‘  ๋ฐ์ดํ„ฐ๋ฅผ ์€๋‹‰ ๋ฐ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
โ‘ก DTO๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์›ํ•˜๋Š” ์ •๋ณด๋งŒ์„ ์ œ๊ณตํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
โ‘ข Entity์˜ ์ •๋ณด๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์›ํ•˜๋Š” ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ๋“ค์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ •๋ณด๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค”ย DAO์™€ DTO์˜ ์ฐจ์ด๋ฅผ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.

  • DTO(Data Transfer Object, ๋ฐ์ดํ„ฐ ์ „์†ก ๊ฐ์ฒด)๋Š” ๋ฐ์ดํ„ฐ ๊ตํ™˜์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฐ์ฒด๋กœ, DB์˜ ๋ฐ์ดํ„ฐ๋ฅผ Controller ํ˜น์€ Service๋กœ ๋ณด๋‚ผ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • DAO(Data Access Object, ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ฐ์ฒด)๋Š” ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฐ์ฒด๋กœ, DB์— ์ ‘๊ทผํ•˜๋Š” ๋กœ์ง๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.



Spring์—์„œ ์˜ˆ์™ธ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.


ํ•ต์‹ฌ๋‹ต๋ณ€

์Šคํ”„๋ง์—์„œ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ 3๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ •ํ™•ํžˆ๋Š” DispatcherServlet์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ๋ฅผ HandlerExceptionResolver๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋“ค์ž…๋‹ˆ๋‹ค.

  1. ๋ฉ”์†Œ๋“œ ๋‹จ์—์„œ, try/catch๋ฌธ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ๋กœ Check Exception์„ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  2. ์ปจํŠธ๋กค๋Ÿฌ๋‹จ์—์„œ @ExceptionHandler ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ๋กœ Controller์˜ ๋ฉ”์„œ๋“œ์—์„œ throw๋œ Exception์— ๋Œ€ํ•ด ๊ณตํ†ต์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒํ•ฉ๋‹ˆ๋‹ค.
  3. ์ปค์Šคํ…€ํ•œ Exception ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด Global Level์—์„œ, ์ปจํŠธ๋กค๋Ÿฌ ์ดํ›„ Client์—๊ฒŒ ์ „๋‹ฌ๋˜๊ธฐ ์ „์— ์ฒ˜๋ฆฌํ•˜๋Š” AOP ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” ExceptionHandler๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

์Šคํ”„๋ง์—์„œ @ExceptionHandler ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ์˜ˆ์™ธ ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•ด์ฃผ๋ฉด, ํ•ด๋‹น ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋ฉ”์„œ๋“œ์—์„œ ์ •์˜ํ•œ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

AOP ๊ด€์ ์—์„œ @RestControllerAdvice ์–ด๋…ธํ…Œ์ด์…˜์„ ํด๋ž˜์Šค์— ์„ ์–ธํ•˜๊ฒŒ ๋˜๋ฉด, ์ปจํŠธ๋กค๋Ÿฌ ๋‹จ์—์„œ ์ผ์–ด๋‚˜๋Š” ๋ชจ๋“  ์—๋Ÿฌ์— ๋Œ€ํ•ด ์ „์—ญ์ ์ธ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

ExceptionHandler๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ „์—ญ์ ์œผ๋กœ ์ผ์–ด๋‚˜๋Š” ์—๋Ÿฌ ์ค‘ ํŠน์ • ์—๋Ÿฌ ํด๋ž˜์Šค์— ์ง€์ •ํ•˜์—ฌ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” Controller์˜ @ExceptionHandler์™€ ControllerAdvice์˜ @ExceptionHandler ์ค‘ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€๊ฒƒ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Controller์˜ @ExceptionHandler๊ฐ€ ๋จผ์ €์ž…๋‹ˆ๋‹ค.

๐Ÿค” HandlerExceptionResolver์— ๋Œ€ํ•ด ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.

HandlerExceptionResolver๋Š” ์ปจํŠธ๋กค๋Ÿฌ ์ž‘์—… ์ค‘ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์ „๋žต์ž…๋‹ˆ๋‹ค.
์•ž์„œ ์„ค๋ช…๋“œ๋ฆฐ @ExceptionHandler ์–ด๋…ธํ…Œ์ด์…˜์„ ํ™œ์šฉํ•˜์—ฌ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ @ControllerAdvice ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปค์Šคํ…€ํ•œ Exception ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์คŒ์œผ๋กœ์จ, Global Level์—์„œ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ HandlerExceptionResolver๋ฅผ ์ด์šฉํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

Dispatcher Servlet์— ๊ธฐ๋ณธ์ ์œผ๋กœ 3๊ฐœ์˜ HandlerExceptionResolver๊ฐ€ ๋“ฑ๋ก ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

  1. ExceptionHandlerExceptionResolver
  2. ResponseStatusExceptionResolver
  3. 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

๐Ÿค” Filter์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•˜๋‚˜์š”?

DisptatcherServlet ๋ฐ–์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ๋กœ HandlerExceptionResolver์˜ ์ฒ˜๋ฆฌ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋Š” Web Application ๋ ˆ๋ฒจ์—์„œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. web.xml์— error-page๋ฅผ ์ž˜ ๋“ฑ๋กํ•ด์ค˜์„œ ์—๋Ÿฌ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์‘๋‹ตํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  2. Filter ๋‚ด๋ถ€์—์„œ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ•„ํ„ฐ๋ฅผ ๋”ฐ๋กœ ๋‘ฌ์„œ try-catch๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  3. Filter ๋‚ด๋ถ€์—์„œ try-catch ๊ตฌ๋ฌธ์„ ํ†ตํ•ด ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ, HandlerExceptionResolver๋ฅผ ๋นˆ์œผ๋กœ ์ฃผ์ž…๋ฐ›์•„ @ExceptionHandler์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
    ์ฆ‰, ํ•„ํ„ฐ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ๋ฅผ ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์ธ HandlerExceptionResolver์— ๋ณด๋‚ด์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.



Filter์™€ Interceptor ์ฐจ์ด


ํ•ต์‹ฌ๋‹ต๋ณ€

ํ•„ํ„ฐ๋Š” 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๋Š” ์–ด๋–ค ๊ฒฝ์šฐ์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์„๊นŒ์š”?

Filter์™€ Interceptor๋Š” ๊ณตํ†ต ์—…๋ฌด๋ฅผ ํ”„๋กœ๊ทธ๋žจ ํ๋ฆ„์˜ ์•ž, ์ค‘๊ฐ„, ๋’ค์— ์ถ”๊ฐ€ํ•˜์—ฌ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ž๋ฐ” ์›น ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด, ๊ณตํ†ต์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ์—…๋ฌด๋“ค์ด ๋งŽ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ๋กœ๊ทธ์ธ ๊ด€๋ จ(์„ธ์…˜ ์ฒดํฌ)์ฒ˜๋ฆฌ, ๊ถŒํ•œ ์ฒดํฌ, XSS(Cross site script)๋ฐฉ์–ด, ํŽ˜์ด์ง€ ์ธ์ฝ”๋”ฉ ๋ณ€ํ™˜ ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๊ณตํ†ต์—…๋ฌด์— ๊ด€๋ จ๋œ ์ฝ”๋“œ๋ฅผ ๋ชจ๋“  ํŽ˜์ด์ง€ ๋งˆ๋‹ค ์ž‘์„ฑ ํ•ด์•ผํ•œ๋‹ค๋ฉด ์ค‘๋ณต๋œ ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง€๊ฒŒ ๋˜๊ณ  ํ”„๋กœ์ ํŠธ ๋‹จ์œ„๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ์„œ๋ฒ„์— ๋ถ€ํ•˜๋ฅผ ์ค„ ์ˆ˜๋„์žˆ์œผ๋ฉฐ, ์†Œ์Šค ๊ด€๋ฆฌ๋„ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฆ‰, ๊ณตํ†ต ๋ถ€๋ถ„์€ ๋นผ์„œ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ ๊ณตํ†ต์—…๋ฌด๋ฅผ ํ”„๋กœ๊ทธ๋žจ ํ๋ฆ„์˜ ์•ž, ์ค‘๊ฐ„, ๋’ค์— ์ถ”๊ฐ€ํ•˜์—ฌ, ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด, Filter์™€ Interceptor๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Filter๋Š” ์ „์ฒด์ ์ธ Request๋‹จ์—์„œ ์–ด๋–ค ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ธ์ฆ, ์ด๋ฏธ์ง€ ๋ณ€ํ™˜, ๋ฐ์ดํ„ฐ ์••์ถ•, ์•”ํ˜ธํ™” ํ•„ํ„ฐ, XML ์ปจํ…์ธ ๋ฅผ ๋ณ€ํ˜•ํ•˜๋Š” XSLT ํ•„ํ„ฐ, URL ๋ฐ ๊ธฐํƒ€์ •๋ณด๋ฅผ ์บ์‹œํ•˜๋Š” ํ•„ํ„ฐ, ๋ฌธ์ž ์ธ์ฝ”๋”ฉ
  • Interceptor๋Š” ์„ธ์…˜ ๋ฐ ์ฟ ํ‚ค ์ฒดํฌ์™€ ๊ฐ™์ด http ํ”„๋กœํ† ์ฝœ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์—…๋ฌด๊ฐ€ ์žˆ์„ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.