๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring

Controller์—์„œ ์˜์กด์„ฑ ์ฃผ์ž… ๋Œ€์ƒ ํ•„๋“œ ๊ฐ’์ด NULL์ด ๋˜๋Š” ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ๋ฐฉ์•ˆ, ์ด์œ 

by ํ‘์‹œ๋ฐ” 2024. 2. 17.

๐Ÿ‘‹ ๋ฐฐ๊ฒฝ

์ปจํŠธ๋กค๋Ÿฌ ๋งคํ•‘ ๋ฉ”์„œ๋“œ์—์„œ ์˜์กด์„ฑ ์ฃผ์ž…๋œ ํ•„๋“œ์— ์ ‘๊ทผํ•˜๋Š”๋ฐ, ํ•ด๋‹น ํ•„๋“œ๊ฐ€ null๋กœ ๋˜์–ด์„œ NullPointException์ด ๋œจ๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ–ˆ๋‹ค.

 

์˜์กด์„ฑ ์ฃผ์ž… ๋Œ€์ƒ ํ•„๋“œ๋Š” ์ปดํฌ๋„ŒํŠธ ์Šค์บ” ๋ฒ”์œ„์—๋„ ํฌํ•จ๋˜์–ด ์žˆ์—ˆ์œผ๋ฉฐ, @Component ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด ๋†“์€ ์ƒํ™ฉ์ด๋ผ ๊ฒฝํ—˜์ƒ์œผ๋กœ ์˜์กด์„ฑ ์ฃผ์ž…๋œ ํ•„๋“œ ๊ฐ’์ด null์ธ ๊ฒƒ์„ ์ดํ•ดํ•  ์ˆ˜ ์—†์—ˆ๋‹ค.

 

ํ•ด๋‹น ๋ฌธ์ œ์— ๋Œ€ํ•ด ์—ฌ๊ธฐ์ €๊ธฐ ์ฐพ์•„๋ณด๋‹ค๊ฐ€ ์›์ธ์„ ์ฐพ๊ณ  ํ•ด๊ฒฐํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

๐Ÿ”Ž ์›์ธ

์–ด์ด์—†๊ฒŒ๋„ ์ปจํŠธ๋กค๋Ÿฌ ๋งคํ•‘ ๋ฉ”์„œ๋“œ์˜ ์ ‘๊ทผ ์ง€์‹œ์ž๊ฐ€ private์ธ ๊ฒƒ์ด ์›์ธ์ด์—ˆ๋‹ค.

 

    @PostMapping("/")
    @ResponseStatus(HttpStatus.OK)
    private ProductResponse.Register register(ProductDto productDto) {
    	...
    }

 

ํ•„์ž๋Š” ์Šต๊ด€์ ์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ private์œผ๋กœ ์ง€์ •ํ•˜๋Š”๋ฐ, ๊ทธ๋Ÿฌ๋‹ค๊ฐ€ ํ•ด๋‹น ๋ถ€๋ถ„์„ ๋†“์ณค๋˜ ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค.

ํ•ด๋‹น ๋ถ€๋ถ„์€ ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋กœ ์žก์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ์ด ๋ถ€๋ถ„์„ ๋†“์นœ๋‹ค๋ฉด ์›์ธ ํŒŒ์•…์„ ์œ„ํ•ด ์‚ฝ์งˆ์„ ํ•˜๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ๋‹ค.

๐Ÿ‘€ ์ด์œ 

๊ทธ๋Ÿฌ๋‹ค๊ฐ€ ๋ฌธ๋“ '์™œ private ๋ฉ”์„œ๋“œ๋Š” ์˜์กด์„ฑ ์ฃผ์ž…๋œ ํ•„๋“œ ๊ฐ’์„ ์ด์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฑธ๊นŒ?' ์˜๋ฌธ์ด ๋“ค์—ˆ๊ณ  ๊ด€๋ จ ๋‚ด์šฉ์— ๋Œ€ํ•ด ์•Œ๊ฒŒ ๋œ ๋‚ด์šฉ์— ๋Œ€ํ•ด ๊ณต์œ ํ•˜๊ณ ์ž ํ•œ๋‹ค.

 

๊ธฐ๋ณธ์ ์œผ๋กœ ์Šคํ”„๋ง ์ปจํŠธ๋กค๋Ÿฌ์˜ ๋งคํ•‘ ๋ฉ”์„œ๋“œ์— private ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ž‘๋™ ๋ฐฉ์‹๊ณผ ์›์น™์— ์–ด๊ธ‹๋‚œ๋‹ค.

 

๋งคํ•‘ ๋ฉ”์„œ๋“œ๋Š” HTTP ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์Šคํ”„๋ง MVC์— ์˜ํ•ด ํ˜ธ์ถœ๋˜๋Š” public ๋ฉ”์„œ๋“œ์ด๋ฏ€๋กœ, ์ด๋Ÿฌํ•œ ๋ฉ”์„œ๋“œ๋Š” ์Šคํ”„๋ง์˜ DispatcherServlet์— ์˜ํ•ด ๋™์ ์œผ๋กœ ํ˜ธ์ถœ๋˜๋ฉฐ, ์ด๋ฅผ ์œ„ํ•ด ๋ฐ˜๋“œ์‹œ public ์ ‘๊ทผ ์ œํ•œ์ž๋ฅผ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.

 

์ถ”๊ฐ€์ ์œผ๋กœ private ๋ฉ”์„œ๋“œ๋ฅผ ๋งคํ•‘ ๋ฉ”์„œ๋“œ๋กœ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๋“ค์ด ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

1. ์ ‘๊ทผ์„ฑ ๋ฌธ์ œ

private ๋ฉ”์„œ๋“œ๋Š” ํด๋ž˜์Šค ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. ์Šคํ”„๋ง์˜ DispatcherServlet์€ ์ปจํŠธ๋กค๋Ÿฌ์˜ public ๋ฉ”์„œ๋“œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, private ๋ฉ”์„œ๋“œ๋Š” ๋งคํ•‘ ๋ฉ”์„œ๋“œ๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์—†๋‹ค.

2. ์Šคํ”„๋ง ๋นˆ ๋ผ์ดํ”„์‚ฌ์ดํด ์œ„๋ฐ˜

์Šคํ”„๋ง์€ ๋นˆ(bean)์˜ ๋ผ์ดํ”„์‚ฌ์ดํด์„ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ปจํŠธ๋กค๋Ÿฌ ๋นˆ์˜ public ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด ์š”์ฒญ ๋งคํ•‘, ์ธํ„ฐ์…‰ํ„ฐ ์ฒ˜๋ฆฌ, AOP ํ”„๋ฝ์‹œ ๋“ฑ์„ ์ ์šฉํ•œ๋‹ค. private ๋ฉ”์„œ๋“œ๋Š” ์ด๋Ÿฌํ•œ ์ฒ˜๋ฆฌ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์—†์–ด, ์Šคํ”„๋ง์˜ ๊ธฐ๋Šฅ์„ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

3. ํ”„๋ ˆ์ž„์›Œํฌ ๊ทœ์•ฝ ์œ„๋ฐ˜

์Šคํ”„๋ง MVC๋Š” ํŠน์ • ๊ทœ์•ฝ์„ ๋”ฐ๋ฅธ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, @RequestMapping์ด๋‚˜ @GetMapping, @PostMapping ๋“ฑ์˜ ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ HTTP ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์ •ํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ์• ๋„ˆํ…Œ์ด์…˜์€ public ๋ฉ”์„œ๋“œ์—๋งŒ ์ ์šฉ๋˜์–ด์•ผ ํ•˜๋ฉฐ, private ๋ฉ”์„œ๋“œ์— ์ ์šฉํ•˜๋Š” ๊ฒƒ์€ ์Šคํ”„๋ง MVC์˜ ์„ค๊ณ„ ์›์น™์— ๋ฐ˜ํ•œ๋‹ค.

4. ๋ฆฌํ”Œ๋ ‰์…˜ ์ œํ•œ

์Šคํ”„๋ง์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฆฌํ”Œ๋ ‰์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปจํŠธ๋กค๋Ÿฌ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ๊ณ  ํ˜ธ์ถœํ•œ๋‹ค. private ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌํ”Œ๋ ‰์…˜์„ ํ†ตํ•ด์„œ๋„ ์ผ๋ฐ˜์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ์Šคํ”„๋ง์ด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ๋งคํ•‘ ๋ฉ”์„œ๋“œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

๐Ÿ“Œ ๊ฒฐ๋ก 

์Šคํ”„๋ง ์ปจํŠธ๋กค๋Ÿฌ์—์„œ๋Š” ๋งคํ•‘ ๋ฉ”์„œ๋“œ๋ฅผ ํ•ญ์ƒ public์œผ๋กœ ์„ ์–ธํ•ด์•ผ ํ•˜๋ฉฐ, private ๋ฉ”์„œ๋“œ๋Š” ๋งคํ•‘ ๋ฉ”์„œ๋“œ๋กœ ์‚ฌ์šฉ๋˜์–ด์„œ๋Š” ์•ˆ ๋œ๋‹ค. ์˜์กด์„ฑ ์ฃผ์ž…๋œ ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, ํ•ด๋‹น ํ•„๋“œ๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๊ณ  ๊ด€๋ฆฌ๋˜๋Š” public ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ“š  REFERENCE

https://stackoverflow.com/questions/70143003/null-exception-service-in-a-spring-restcontroller-using-constructor-injection

๋Œ“๊ธ€