[SPRING] Bean๐Ÿซ›, IoC, DI, @ComponentScan

๋ฆผ๋ฏผ์ง€ยท2025๋…„ 3์›” 27์ผ

Today I Learn

๋ชฉ๋ก ๋ณด๊ธฐ
34/62

๐Ÿ—„๏ธ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ & ๋นˆ

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ

: ๊ฐ์ฒด(Bean)๋ฅผ ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌํ•˜๊ณ  ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ์—ญํ• 
์—ฌ๊ธฐ์„œ ์ด ๋นˆ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์˜ ๋‹ด๋‹น์ž๋Š” ๋ฐ”๋กœ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์ž„ใ…‹

๐Ÿซ› ๋นˆ Bean

: Spring ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด
โ†’ ์›๋ž˜๋Š” ๊ทธ๋ƒฅ ์ž๋ฐ” ๊ฐ์ฒด๊ฐ€ ์Šคํ”„๋ง์„ ๋งŒ๋‚˜์„œ ์Šคํ”„๋ง์ด ์ด ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋˜๋ฉด์„œ ๊ทธ ์ˆœ๊ฐ„๋ถ€ํ„ฐ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ๋นˆ์ด ๋˜๋Š” ๊ฒƒ!
(new ํ‚ค์›Œ๋“œ๋ฅผ ์“ฐ์ง€ ์•Š๊ณ ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค)

< Spring Bean์˜ ํŠน์ง• >
1. Spring ์ปจํ…Œ์ด๋„ˆ์— ์˜ํ•ด ์ƒ์„ฑ๋˜๊ณ  ๊ด€๋ฆฌ๋œ๋‹ค.
2. ๊ธฐ๋ณธ์ ์œผ๋กœ Singleton์œผ๋กœ ์„ค์ •๋œ๋‹ค.
3. ์˜์กด์„ฑ ์ฃผ์ž…(DI)์„ ํ†ตํ•ด ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๊ณผ ์˜์กด ๊ด€๊ณ„๋ฅผ ๋งบ์„ ์ˆ˜ ์žˆ๋‹ค.
4. ์ƒ์„ฑ, ์ดˆ๊ธฐํ™”, ์‚ฌ์šฉ, ์†Œ๋ฉธ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง„๋‹ค.

Bean์€ ํ•ญ์ƒ ์‹ฑ๊ธ€ํ†ค

์ˆ˜๋™ ๋นˆ ๋“ฑ๋ก์ด ์ž๋™ ๋นˆ ๋“ฑ๋ก์„ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•ด์„œ ์šฐ์„ ๊ถŒ
-> ์ข€ ๋” ์ž์„ธํžˆ ์ž‘์„ฑ๋œ ๋นˆ์ด ์šฐ์„ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด๋จ์—ฌ

๋นˆ์„ ์“ฐ๋ฉด ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ์‘์ง‘๋„๋ฅผ ๋†’์—ฌ์„œ ๋…๋ฆฝ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์‚ผ
singletonํŒจํ„ด์„ ๊ฐ€์ง€๋Š”๋ฐ ์ด๊ฑฐ ๋•๋ถ„์— ์—ฌ๊ธฐ์ €๊ธฐ์„œ ๋ง‰ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•ด๊ฐ€์ง€๊ณ  ๋ง‰ ์“ธ์ˆ˜์ž‡์Œ


๐Ÿ’‰ ์˜์กด์„ฑ ์ฃผ์ž…(DI) & ์ œ์–ด์˜ ์—ญ์ „(IoC)

์˜์กด์„ฑ ์ฃผ์ž…(DI)๊ณผ ์ œ์–ด์˜ ์—ญ์ „(IoC)์„ ํ†ตํ•ด ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๊ณผ ์˜์กด ๊ด€๊ณ„๋ฅผ ๋งบ์„ ์ˆ˜ ์žˆ๋‹ค

1. IOC(์ œ์–ด์˜ ์—ญ์ „, Inversion Of Control)

: ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ๊ด€๋ฆฌ ๊ถŒํ•œ์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹Œ Spring ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋‹ด๋‹นํ•˜๋Š” ๊ฒƒ
์ฆ‰, ์Šคํ”„๋ง์ด ๊ฐ์ฒด๋ฅผ ๋Œ€์‹  ๊ด€๋ฆฌํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ

2. ์˜์กด์„ฑ ์ฃผ์ž…(DI)

: Spring์ด ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด์„ฑ์„ ์ž๋™์œผ๋กœ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ๊ฒƒ
์Šคํ”„๋ง์ด ์•Œ๋งž์€ ๊ฐ์ฒด๋ฅผ ์•Œ์•„์„œ ๊ฐ€์ ธ๋‹ค ์”€(ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑ(new)ํ•˜์ง€ ์•Š๊ณ  Spring์ด ์ฃผ์ž…)
โ†’ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ๋งŒ๋“ค ํ•„์š” ์—†์ด, ํ•„์š”ํ•œ ๊ณณ์—์„œ "์ด๊ฑฐ ์ฃผ์„ธ์š”!" ํ•˜๋ฉด ๋จ!
โ†’ ์Šคํ”„๋ง์ด ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ํ•„์š”ํ•œ ๊ณณ์— ์ž๋™์œผ๋กœ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ" (IoC์˜ ํ•œ ๋ฐฉ์‹)

๊ฐœ๋ฐœ์ž๊ฐ€ ์–ด ๋ฌด์Šจ ๊ฐ์ฒด ํ•„์š”ํ•˜๋‹ค~ ํ•˜๋ฉด ์•Œ์•„์„œ ๊ทธ๊ฑฐ์— ๋งž๋Š” ๊ฐ์ฒด ๊ฐ€์ ธ์™€๊ฐ€์ง€๊ณ  ๋งž๋Š” ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์คŒ

๐Ÿ’ก ์žฅ์ 

  • ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›€
  • ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”์–ด ๋…๋ฆฝ์„ฑ์„ ๋†’์—ฌ์คŒ

IoC๋Š” ๋” ํฐ ๊ฐœ๋…
DI๋Š” IoC๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜

๐Ÿ’ญ ๋น„์œ ํ•˜์ž๋ฉด...
IoC = "ํšŒ์‚ฌ๊ฐ€ ์ง์›(๊ฐ์ฒด) ๊ด€๋ฆฌ๋ฅผ ์ง์ ‘ ์•ˆ ํ•˜๊ณ , HR(์Šคํ”„๋ง)์ด ๊ด€๋ฆฌํ•˜๊ฒŒ ๋งก๊ธฐ๋Š” ๊ฒƒ"
DI = "HR(์Šคํ”„๋ง)์ด ๊ฐ ๋ถ€์„œ์— ํ•„์š”ํ•œ ์ง์›(๊ฐ์ฒด)์„ ์ž๋™์œผ๋กœ ๋ฐฐ์น˜ํ•ด ์ฃผ๋Š” ๊ฒƒ"

โœ… IoC โ†’ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ , ์Šคํ”„๋ง์ด ์•Œ์•„์„œ ๊ด€๋ฆฌ!
โœ… DI โ†’ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ new ์•ˆ ํ•ด๋„, ํ•„์š”ํ•œ ๊ฐ์ฒด๋ฅผ ์Šคํ”„๋ง์ด ์ž๋™์œผ๋กœ ์ฃผ์ž…!


๐Ÿ–จ๏ธ @ComponentScan

: Spring์ด ํŠน์ • ํŒจํ‚ค์ง€ ๋‚ด์—์„œ Annotation(@Component, @Service, @Repository ๋“ฑ)์ด ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ์ž๋™์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ณ , ์ด๋ฅผ Bean์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๊ธฐ๋Šฅ

์ด์ „ ํˆฌ๋‘ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๋•Œ ํด๋ž˜์Šค๋ณ„๋กœ @Repository @Conroller @Servie ๋“ฑ์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์—ฌ์คฌ์—ˆ๋‹ค.
์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด Spring์ด ๊ฐ ํด๋ž˜์Šค๋ฅผ ๊ฐ๊ฐ์— ๋งž๋Š” ๋นˆ์œผ๋กœ ์ž๋™ ๋“ฑ๋กํ–ˆ์—ˆ๋‹ค

๐Ÿ‘‰ ComponentScan ๋•๋ถ„์— ๋„ค๊ฐ€ ์ง์ ‘ Bean ๋“ฑ๋ก์„ ํ•˜์ง€ ์•Š์•„๋„, Spring์ด ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋“ค์„ ์ฐพ์•„์„œ ์ž๋™์œผ๋กœ ๋นˆ์œผ๋กœ ๊ด€๋ฆฌ!

๊ทธ๋Ÿฌ๋‹ˆ๊นŒ @Service ๊ฐ™์€ ๊ฑธ ๋‹ฌ์•„๋‘๊ธฐ๋งŒ ํ•˜๋ฉด, ์Šคํ”„๋ง "์•„ ์ด๊ฑฐ Bean์œผ๋กœ ๋“ฑ๋กํ•˜๋ผ๋Š”๊ฑฐ๊ตฐ ใ…‹" ํ•˜๊ณ  ์•Œ์•„์„œ ์ฒ˜๋ฆฌํ•˜๋Š”๊ฑฐ~~~ ์งฑํŽธํ•˜์ฃ ?

๐Ÿ“ basePackages

: ํŠน์ • ํŒจํ‚ค์ง€๋ฅผ ์Šค์บ”ํ•  ๋•Œ ์‚ฌ์šฉ, ๋ฐฐ์—ด๋กœ ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๋Ÿฌ๊ฐœ์˜ ํŒจํ‚ค์ง€๊ฐ€ ์กด์žฌํ• ๋•Œ, ์Šคํ”„๋ง์ด ์–ด๋–ค ํŒจํ‚ค์ง€์—์„œ ์–ด๋–ค ์–ด๋…ธํ…Œ์ด์…˜์„ ์ฝ์–ด์•ผํ• ์ง€ ํ˜ผ๋ž€์Šค๋Ÿฝ์ž–์•„? ๊ทธ๋•Œ basePackges๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์–ด๋–ค ํŒจํ‚ค์ง€์— ์žˆ๋Š” ๊ฒƒ๋“ค์„ ์‚ฌ์šฉํ• ๊ฑด์ง€ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค~~
- ์˜ˆ์‹œ: @ComponentScan(basePackages = {"com.example", "com.another"})

@ComponentScan ์ž‘๋™ ์ˆœ์„œ

  1. Spring Application์ด ์‹คํ–‰๋˜๋ฉด @ComponentScan์ด ์ง€์ •๋œ ํŒจํ‚ค์ง€๋ฅผ ํƒ์ƒ‰
  2. ํ•ด๋‹น ํŒจํ‚ค์ง€์—์„œ Annotation์ด ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ์ฐพ๊ธฐ
  3. ์ฐพ์€ ํด๋ž˜์Šค๋ฅผ Spring ์ปจํ…Œ์ด๋„ˆ์— ๋นˆ์œผ๋กœ ๋“ฑ๋ก.
  4. ๋“ฑ๋ก๋œ ๋นˆ์€ ์˜์กด์„ฑ ์ฃผ์ž…(DI)๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋‹ค๋ฅธ ๋นˆ๊ณผ ์—ฐ๊ฒฐ

๐ŸŽฏ ์˜ˆ์‹œ๋กœ ์ •๋ฆฌ

๐Ÿ›’ ComponentScan = "์ฐฝ๊ณ ์—์„œ ์žฌ๋ฃŒ(๋นˆ)๋ฅผ ๋ฏธ๋ฆฌ ์ฐพ์•„ ์ค€๋น„ํ•˜๋Š” ๊ด€๋ฆฌ์ž"
๐Ÿ‘จโ€๐Ÿณ DI = "์‰ํ”„๊ฐ€ ํ•„์š”ํ•œ ์žฌ๋ฃŒ๋ฅผ ์š”์ฒญํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ œ๊ณต"

โ†’ ๊ฐœ๋ฐœ์ž๋Š” ์ง์ ‘ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ํ•„์š” ์—†์ด, ํ•„์š”ํ•œ ๊ณณ์—์„œ ์š”์ฒญ๋งŒ ํ•˜๋ฉด ๋!! ๐Ÿš€๐Ÿ”ฅ


๐ŸŽฏ ์˜์กด์„ฑ ์ฃผ์ž…(DI) ๋ฐฉ์‹ - ์ƒ์„ฑ์ž ์ฃผ์ž…

โญ๏ธ @Autowired : ์˜์กด์„ฑ์„ ์ž๋™์œผ๋กœ ์ฃผ์ž…ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Annotation

๊ฐ€์žฅ ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹์ด๋‹ค

1. ์ƒ์„ฑ์ž ์ฃผ์ž…

์ƒ์„ฑ์ž๋กœ ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์„œ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹
๊ฐ€์žฅ ์•ˆ์ •์ ์ด๊ณ , ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ถ”์ฒœ๋œ๋‹ค

@Service
public class OrderService {
    private final PaymentService paymentService;

    @Autowired // ๐Ÿ”ฅ ์ƒ์„ฑ์ž ์ฃผ์ž…
    public OrderService(PaymentService paymentService) { 
        this.paymentService = paymentService;
    }
}

ํ•„๋“œ์— final ์€ ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ์‹๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

2. @RequiredArgsConstructor

:final ํ•„๋“œ๋ฅผ ๋ชจ์•„์„œ ์ƒ์„ฑ์ž๋ฅผ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ์—ญํ• 
Annotation Processor ๊ฐ€ ๋™์ž‘ โ†’ ์ปดํŒŒ์ผ ์‹œ์ ์— ์ž๋™์œผ๋กœ ์ƒ์„ฑ์ž ์ฝ”๋“œ ์ƒ์„ฑ

@Component
@RequiredArgsConstructor //โญ๏ธ ์ƒ์„ฑ์ž ์ž๋™ ์ฃผ์ž…
public class MyApp {
		
    private final MyService myService;

    public void run() {
        myService.doSomething();
    }
    
}

์ด๋–„, ํ•„๋“œ์— final ํ‚ค์›Œ๋“œ๋Š” ํ•„์ˆ˜!
โ†’ ๋ฌด์กฐ๊ฑด ๊ฐ’์ด ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ค€๋‹ค


โš ๏ธ Spring Validation & BindingResult

1. Validation

Spring์—์„œ Validation์€ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ํšจํ•œ์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •!
โ†’ ์ž˜๋ชป๋œ ๋ฐ์ดํ„ฐ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ , ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ

๋ฏธ๋ฆฌ ์ •ํ•ด๋†“์€ ์‚ฌํ•ญ์— ๋ถ€ํ•ฉํ•˜๋Š”์ง€ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ธ๋ฐ,
์˜ˆ๋ฅผ ๋“ค์–ด ์‹๋‹น ๋ฉ”๋‰ดํŒ์— ์—†๋Š” ๋ฉ”๋‰ด๋ฅผ ์ฃผ๋ฌธํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ํŠน์ • ๋ฐ์ดํ„ฐ ํ˜•์‹๊ณผ ๊ฐ’์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๋Š”๊ฒƒ!

โ“ ์™œ ํ•ด์•ผํ• ๊นŒ?

  • ์ž˜๋ชป๋œ ์ž…๋ ฅ๊ฐ’์œผ๋กœ ์ธํ•ด ์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์ด ๋‚˜๋น ์ง
  • ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ์ž‘์„ฑ ์ค‘์ด๋˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๋ฉด ๋ถˆํŽธํ•จ์ด ํผ
  • ์ ์ ˆํ•œ ๊ฒ€์ฆ์„ ํ†ตํ•ด ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ , ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ช…ํ™•ํ•œ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•ด์•ผ ํ•จ

ํ”„๋ก ํŠธ์—”๋“œ / ์„œ๋ฒ„ / ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฒ€์ฆ 3๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ ์ด ์ค‘์—์„œ๋„
์„œ๋ฒ„ ๊ฒ€์ฆ์ด ํ•„์ˆ˜์ด๋‹ค
โ†’ API์—์„œ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์ˆ˜ํ–‰
โ†’ ๊ฒ€์ฆ ์‹คํŒจ ์‹œ ์ ์ ˆํ•œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•จ

2. BindingResult

: Validation ์˜ค๋ฅ˜๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด

@ModelAttribute ๋กœ ์ „๋‹ฌ๋œ ๋ฐ์ดํ„ฐ์—์„œ ๊ฒ€์ฆ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด BindingResult ๊ฐ€ ์ด๋ฅผ ๋ณด๊ด€!

๐Ÿ‘Ž ๋งŒ์•ฝ BindingResult๊ฐ€ ์—†์œผ๋ฉด?
์š”์ฒญ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ ์‹คํŒจ ์‹œ 400 Bad Request ๋ฐœ์ƒ
์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๊ณ , ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์˜ค๋ฅ˜ ํŽ˜์ด์ง€๋กœ ์ด๋™

๐Ÿ‘ BindingResult๊ฐ€ ์žˆ์œผ๋ฉด!!!!
@ModelAttribute ๋ฐ”์ธ๋”ฉ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ, BindingResult๊ฐ€ ์˜ค๋ฅ˜ ์ •๋ณด ์ €์žฅ
์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ํ˜ธ์ถœ, ๊ฒ€์ฆ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ํ•„๋“œ๋ฅผ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ๊ฐ’์ด ๋ฐ”์ธ๋”ฉ

๐Ÿ BindingResult๋Š” ๊ฒ€์ฆํ•  ๊ฐ์ฒด ๋’ค์— ์œ„์น˜ํ•ด์•ผ๋งŒ ํ•จ

โžก๏ธ ์ด๋Ÿฌํ•œ ๊ฒ€์ฆ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ํ–ฅ์ƒ ๋ฐ ์˜ค๋ฅ˜ ๋ฐฉ์ง€ ๊ฐ€๋Šฅ

0๊ฐœ์˜ ๋Œ“๊ธ€