[Spring] DI(์˜์กด์„ฑ ์ฃผ์ž…): ์™œ ํ•„์š”ํ•˜๊ณ  ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ• ๊นŒ?

2025. 2. 7. 16:49ยท๐Ÿ’ชBackend/Spring

 

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ(Spring Framework)์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜๋Š” DI(Dependency Injection, ์˜์กด์„ฑ ์ฃผ์ž…)์ž…๋‹ˆ๋‹ค. DI๋ฅผ ์ดํ•ดํ•˜๋ฉด ๋ณด๋‹ค ์œ ์—ฐํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” DI๊ฐ€ ๋ฌด์—‡์ธ์ง€, ์™œ ํ•„์š”ํ•œ์ง€, ๊ทธ๋ฆฌ๊ณ  ์Šคํ”„๋ง์—์„œ DI๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

 


1. ์˜์กด์„ฑ(Dependency)์ด๋ž€?

ํ•˜๋‚˜์˜ ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” ๊ด€๊ณ„๋ฅผ ๋œปํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, ํ•˜๋‚˜์˜ ๊ฐ์ฒด๊ฐ€ ๋™์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์ €๋Š” ์•ž์œผ๋กœ ์˜์กด๊ณผ ์‚ฌ์šฉ์„ ๋™์ผํ•œ ์˜๋ฏธ๋กœ ์–ธ๊ธ‰ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! (feat. ์†ก์•„์Œค)

 

 

์˜ˆ์ œ๋ฅผ ๋ณด์ž๋ฉด,

public class ProductController {
    private ProductService productService = new ProductService();
    
    public String findProductName(){
    	productService.findProductName();
    }
}

์œ„์ฒ˜๋Ÿผ ProductController์—์„œ ProductService๋ฅผ ์ง์ ‘ ์ƒ์„ฑ(new ProductService())ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ(Tight Coupling)์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

 

์ฆ‰, ProductController ํด๋ž˜์Šค๋Š” ProductService ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉ(=์˜์กด)ํ•˜๋ฉฐ, ProductService๊ฐ€ ์—†๋‹ค๋ฉด ProductController๋„ ์ •์ƒ์œผ๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ์˜์กด๋„๋ฅผ ๋‚ฎ์ถ”๊ธฐ ์œ„ํ•ด ์Šคํ”„๋ง์—์„œ๋Š” DI(์˜์กด์„ฑ ์ฃผ์ž…)๋ผ๋Š” ๊ฐœ๋…์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค!

 

 

 

 

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

๊ฐ์ฒด๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ์˜์กด์„ฑ์„ ์ง์ ‘ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ์™ธ๋ถ€์—์„œ ์ฃผ์ž…๋ฐ›๋„๋ก ํ•˜๋Š” ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ํด๋ž˜์Šค ๊ฐ„ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ์ฝ”๋“œ์˜ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

์œ„์˜ ์˜ˆ์ œ๋ฅผ DI ๋ฐฉ์‹์œผ๋กœ ์ˆ˜์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public class ProductController {
    private final ProductService productService;
    
    // ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ์‹
    public ProductController(ProductService productService){
    	this.productService = proudctService;
    }
    
    public String findProductName(){
    	productService.findProductName();
    }
}

ProductController๋Š” ์ด์ „์ฒ˜๋Ÿผ productService๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„์ง‘๋‹ˆ๋‹ค. 

๋˜ํ•œ, DI๋ฅผ ํ†ตํ•ด IoC๋ฅผ ์‹คํ˜„ํ•˜๋ฏ€๋กœ ๊ฐ์ฒด ๋ผ์ดํ”„ ์‚ฌ์ดํด์„ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(+ ์Šคํ”„๋ง์˜ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ํ†ตํ•ด ๊ฐ์ฒด ์žฌ์‚ฌ์šฉ๋„ ๊ฐ€๋Šฅ)

 

 

ProductService(interface)์— ์†ํ•˜๋Š” ๊ฐ์ฒด(ProductAService, ProductBService)๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๋ผ๋ฉด,

DI๋ฅผ ์ ์šฉํ•˜๊ธฐ ์ „์˜ ๋ฐฉ๋ฒ•์—์„œ๋Š” ์ด๋ฅผ ProductController๊ฐ€ ์ง์ ‘ ์–ด๋–ค ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์ง€ ์„ ํƒํ•ด์•ผ ํ•˜๊ณ 

DI๋ฅผ ์ ์šฉํ•œ ํ›„์—๋Š” ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์ฒด๊ฐ€ ์•„๋‹Œ ProductService์—๋งŒ ์˜์กดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

 

 

 

๊ทธ๋Ÿผ ์ด๋Ÿฐ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ์–ด๋– ํ•œ ๊ฒƒ๋“ค์ด ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

3. DI(์˜์กด์„ฑ ์ฃผ์ž…) ๋ฐฉ๋ฒ• 3๊ฐ€์ง€

 

Setter Injection(setter ์ฃผ์ž…)

Setter ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

@Controller
public class ProductController {
    private ProductService productService;
    
    //setter ์ฃผ์ž…
    @Autowired
    public void setProductService(ProductService productService){
    	this.productService = proudctService;
    }
    
    public String findProductName(){
    	productService.findProductName();
    }
}

 

ProductController๊ฐ€ ์ƒ์„ฑ๋œ ํ›„ setter๋ฅผ ํ†ตํ•ด ProductService๋ฅผ ์ฃผ์ž…๋ฐ›๋Š”๋‹ค. (=final ๋ถˆ๊ฐ€)

setter๊ฐ€ public ๊ถŒํ•œ์ด๊ธฐ์— ์–ด๋””์„œ๋“  setter๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ProductService๋ฅผ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋˜ํ•œ, ํ•„์ˆ˜ ์˜์กด์„ฑ์ด ํœด๋จผ์—๋Ÿฌ๋กœ ์ฃผ์ž…๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

Field Injection(ํ•„๋“œ ์ฃผ์ž…) - ์ง€์–‘๐Ÿ˜ข

setter ์ฃผ์ž…์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด ํ•„๋“œ์— ์ง์ ‘ @Autowired๋ฅผ ์ ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด ์ƒ๊ฒจ๋‚ฌ์Šต๋‹ˆ๋‹ค.

@Controller
public class ProductController {

    @Autowired
    private ProductService productService;
    
    public String findProductName(){
    	productService.findProductName();
    }
}

3๊ฐ€์ง€ ๋ฐฉ๋ฒ• ์ค‘ ๊ฐ€์žฅ ๊ฐ„๊ฒฐํ•˜์ง€๋งŒ, ํด๋ž˜์Šค ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜์—ฌ ํ…Œ์ŠคํŠธ๊ฐ€ ์–ด๋ ต๋‹ค.

๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋“ค์€ DI ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์—†๋”๋ผ๋„ ์ •์ƒ ์ž‘๋™์ด ๊ฐ€๋Šฅํ•˜๋‚˜, ํ•ด๋‹น ๋ฐฉ๋ฒ•์€ DI ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋„์›€ ์—†์ด๋Š” ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€ํ•˜๋‹ค.

TDD๊ฐ€ ๋ณดํŽธํ™”๋จ์— ๋”ฐ๋ผ ํ•ด๋‹น ๋ฐฉ๋ฒ•์€ ์ง€์–‘๋œ๋‹ค.

 

 

 

 

Constructor Injection(์ƒ์„ฑ์ž ์ฃผ์ž…) - ๊ถŒ์žฅ๐Ÿ‘

@Controller
public class ProductController {
    private final ProductService productService;
    
    @Autowired
    public ProductController(ProductService productService){
    	this.productService = productService;
	}
    
    public String findProductName(){
    	productService.findProductName();
    }
}

 

final ํ‚ค์›Œ๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. (๋Œ€๋ถ€๋ถ„์˜ ์˜์กด ๊ด€๊ณ„๋Š” ์‹คํ–‰ ํ›„ ์ข…๋ฃŒ๊นŒ์ง€ ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.)

์ˆœ์ˆ˜ ์ž๋ฐ” ์ฝ”๋“œ์™€ ๊ฐ€์žฅ ๋น„์Šทํ•œ ์ฝ”๋“œ๋กœ ๊ฐ์ฒด ์ง€ํ–ฅ์˜ ํŠน์ง•์ด ์ž˜ ๋‚˜ํƒ€๋‚œ๋‹ค.

ํ•„์ˆ˜ ์˜์กด์„ฑ์„ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํœด๋จผ ์—๋Ÿฌ์˜ ๊ฐ€๋Šฅ์„ฑ์ด ๋‚ฎ๋‹ค.

 

 

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ Constructor Injection ๋ฐฉ์‹์„ ๊ฐ€์žฅ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋” ์ž์„ธํ•œ ๋‚ด์šฉ์ด ๊ถ๊ธˆํ•˜์‹  ๋ถ„์€ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๊ธธ..!!

 

 

 

 

 

https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-collaborators.html#beans-constructor-injection

 

Dependency Injection :: Spring Framework

Constructor-based DI is accomplished by the container invoking a constructor with a number of arguments, each representing a dependency. Calling a static factory method with specific arguments to construct the bean is nearly equivalent, and this discussion

docs.spring.io

 

 

 

๊ทธ๋Ÿผ ์•ˆ๋…•... ~

 

'๐Ÿ’ชBackend > Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Spring Batch ๋„์ž…๊ธฐ!! - Tasklet vs Chunk, ๋ญ๊ฐ€ ๋‹ค๋ฅธ๋ฐ? (#2)  (0) 2025.07.05
Spring Batch ๋„์ž…๊ธฐ!! - @Scheduled๋กœ๋Š” ๋ถ€์กฑํ–ˆ๋‹ค(#1)  (1) 2025.07.03
MSA์—์„œ Response Entity์™€ Response custom class๋กœ ์‘๋‹ต ํ†ต์ผํ•˜๊ธฐ  (2) 2025.03.04
'๐Ÿ’ชBackend/Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • Spring Batch ๋„์ž…๊ธฐ!! - Tasklet vs Chunk, ๋ญ๊ฐ€ ๋‹ค๋ฅธ๋ฐ? (#2)
  • Spring Batch ๋„์ž…๊ธฐ!! - @Scheduled๋กœ๋Š” ๋ถ€์กฑํ–ˆ๋‹ค(#1)
  • MSA์—์„œ Response Entity์™€ Response custom class๋กœ ์‘๋‹ต ํ†ต์ผํ•˜๊ธฐ
.๋ฐ.
.๋ฐ.
  • .๋ฐ.
    Do IT
    .๋ฐ.
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • All (40)
      • ๐Ÿ’ป ์•Œ๊ณ ๋ฆฌ์ฆ˜ (21)
        • PS (16)
        • SQL (4)
        • ์ด๋ก  (5)
      • ๐ŸŽˆcapstone (2)
      • ๐Ÿ’ชBackend (12)
        • Django (8)
        • Spring (4)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ๋งํฌ

  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ๋ฌธ์ œํ’€์ด
    BFS
    ์ฝ”ํ…Œ
    python
    crud
    ์Šค์ผ€์ค„๋Ÿฌ
    bruteforce
    SQL
    ์•Œ๊ณ ๋ฆฌ์ฆ˜
    Batch
    PS
    responsecustomclass
    ์„œ๋ธŒ์ฟผ๋ฆฌ
    resposneentity
    programmers
    ์ž๋ฐ”
    ์žฌ๊ท€
    ETL
    ์Šคํ”„๋ง๋ฐฐ์น˜
    springscheduler
    ํŒŒ์ด์ฌ
    apiresponse
    ์‘๋‹ตํ˜•์‹
    MYSQL
    ๋‹ค์ค‘์กฐ์ธ
    Django
    windowํ•จ์ˆ˜
    BOJ
    ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค
    ๋ฐฑ์ค€
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
.๋ฐ.
[Spring] DI(์˜์กด์„ฑ ์ฃผ์ž…): ์™œ ํ•„์š”ํ•˜๊ณ  ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ• ๊นŒ?
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”