Spring ํŠน์ง•(2): DI

0

Spring

๋ชฉ๋ก ๋ณด๊ธฐ
6/10
post-thumbnail

๐Ÿ“Œ 1. ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection, DI)์˜ ๊ฐœ๋…


๐Ÿ“Ž ์˜์กด์„ฑ ์ฃผ์ž…์ด๋ž€?

Spring ํ”„๋ ˆ์ž„์›Œํฌ๋Š” 3๊ฐ€์ง€ ํ•ต์‹ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์„ ์ง€์›ํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ๊ทธ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection, DI)์ด๋‹ค.

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

์œ„์‚ฌ์ง„์—์„œ ๋ณด๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ์ฒซ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ A๊ฐ์ฒด๊ฐ€ B์™€ C๊ฐ์ฒด๋ฅผ New ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด์„œ ์ง์ ‘ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๊ณ ,

๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ setter()๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๋‘๋ฒˆ์งธ ๋ฐฉ์‹์ด ์˜์กด์„ฑ ์ฃผ์ž…์˜ ์˜ˆ์‹œ์ธ๋ฐ, A๊ฐ์ฒด์—์„œ B,C๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉ(์˜์กด)ํ• ๋•Œ A๊ฐ์ฒด์—์„œ ์ง์ ‘ ์ƒ์„ฑ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์™ธ๋ถ€(IOC์ปจํ…Œ์ด๋„ˆ)์—์„œ ์ƒ์„ฑ๋œ B, C๊ฐ์ฒด๋ฅผ ์กฐ๋ฆฝ(์ฃผ์ž…)์‹œ์ผœ setter ํ˜น์€ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

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


๐Ÿ“Ž ์˜์กด์„ฑ ์ฃผ์ž… ์žฅ์  9๊ฐ€์ง€

  1. ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์—ฌ์ค€๋‹ค.
  2. ํ…Œ์ŠคํŠธ์— ์šฉ์ดํ•˜๋‹ค.
  3. ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ™” ์‹œ์ผœ์ค€๋‹ค.
  4. ์ข…์†์ ์ด๋˜ ์ฝ”๋“œ์˜ ์ˆ˜๋„ ์ค„์—ฌ์ค€๋‹ค.
  5. ์™œ ์‚ฌ์šฉํ•˜๋Š” ์ง€ ํŒŒ์•…ํ•˜๊ธฐ๊ฐ€ ์ˆ˜์›”ํ•˜๋‹ค. ์ฝ”๋“œ๋ฅผ ์ฝ๊ธฐ ์‰ฌ์›Œ์ง€๋Š” ์ ์ด ์žˆ๋‹ค.
  6. ์ข…์†์„ฑ์ด ๊ฐ์†Œํ•œ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ข…์†์„ฑ์ด ๊ฐ์†Œํ•˜๋ฉด, ๋ณ€๊ฒฝ์— ๋ฏผ๊ฐํ•˜์ง€ ์•Š๋‹ค.
  7. ๊ฒฐํ•ฉ๋„(coupling)๋Š” ๋‚ฎ์ถ”๋ฉด์„œ ์œ ์—ฐ์„ฑ๊ณผ ํ™•์žฅ์„ฑ์€ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
  8. ๊ฐ์ฒด๊ฐ„์˜ ์˜์กด๊ด€๊ณ„๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  9. ๊ฐ์ฒด๊ฐ„์˜ ์˜์กด๊ด€๊ณ„๋ฅผ ์—†์• ๊ฑฐ๋‚˜ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ“Œ 2. ์˜์กด์„ฑ ์ฃผ์ž… ๊ตฌ์ฒด์  ์˜ˆ์‹œ


๐Ÿ“Ž ์˜์กด์„ฑ์ฃผ์ž…์˜ ์˜ˆ์‹œ

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด Store ๊ฐ์ฒด๊ฐ€ Pencil ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ์— ์šฐ๋ฆฌ๋Š” Store๊ฐ์ฒด๊ฐ€ Pencil ๊ฐ์ฒด์— ์˜์กด์„ฑ์ด ์žˆ๋‹ค๊ณ  ํ‘œํ˜„ํ•œ๋‹ค.

public class Pencil {

}
public class Store{

    private Pencil pencil;

    public Store() {
      this.pencil = new Pencil();
    }

}

๐Ÿ“Ž ์˜์กด์„ฑ์ฃผ์ž…์ด ํ•„์š”ํ•œ ์ด์œ 

ํ•˜์ง€๋งŒ ์œ„์™€ ๊ฐ™์€ ์˜ˆ์‹œ ํด๋ž˜์Šค๋Š” ํฌ๊ฒŒ 2๊ฐ€์ง€ ๋ฌธ์ œ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

๐Ÿ‘‰ ๋‘ ํด๋ž˜์Šค๊ฐ€ ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์–ด ์žˆ๋‹ค.

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

๐Ÿ‘‰ ๊ฐ์ฒด๋“ค ๊ฐ„์˜ ๊ด€๊ณ„๊ฐ€ ์•„๋‹ˆ๋ผ ํด๋ž˜์Šค ๊ฐ„์˜ ๊ด€๊ณ„๊ฐ€ ๋งบ์–ด์ง€๊ณ  ์žˆ๋‹ค.

๋˜ํ•œ ์œ„์˜ Store์™€ Pencil๋Š” ๊ฐ์ฒด๋“ค ๊ฐ„์˜ ๊ด€๊ณ„๊ฐ€ ์•„๋‹ˆ๋ผ ํด๋ž˜์Šค๋“ค ๊ฐ„์˜ ๊ด€๊ณ„๊ฐ€ ๋งบ์–ด์ ธ ์žˆ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ ๊ฐ์ฒด์ง€ํ–ฅ์  ์„ค๊ณ„๋ผ๋ฉด ๊ฐ์ฒด๋“ค ๊ฐ„์— ๊ด€๊ณ„๊ฐ€ ๋งบ์–ด์ ธ์•ผ ํ•˜์ง€๋งŒ ํ˜„์žฌ๋Š” Store ํด๋ž˜์Šค์™€ Pencil ํด๋ž˜์Šค๊ฐ€ ๊ด€๊ณ„๋ฅผ ๋งบ๊ณ  ์žˆ๋‹ค. ๊ฐ์ฒด๋“ค ๊ฐ„์— ๊ด€๊ณ„๊ฐ€ ๋งบ์–ด์กŒ๋‹ค๋ฉด ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ๊ตฌ์ฒด ํด๋ž˜์Šค(Pencil์ธ์ง€ Food์ธ์ง€ ๋“ฑ)๋ฅผ ์ „ํ˜€ ์•Œ์ง€ ๋ชปํ•˜๋”๋ผ๋„, ์ธํ„ฐํŽ˜์ด์Šค์˜ ํƒ€์ž…(Product)์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Ž ์˜์กด์„ฑ์ฃผ์ž…์„ ํ†ตํ•œ ๋ฌธ์ œ ํ•ด๊ฒฐ

๐Ÿ‘‰ ์œ„์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์šฐ์„  ๋‹คํ˜•์„ฑ์ด ํ•„์š”ํ•˜๋‹ค. Pencil, Food ๋“ฑ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ œํ’ˆ์„ ํ•˜๋‚˜๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Product๋ผ๋Š” Interface๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  Pencil์—์„œ Product ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์šฐ์„  ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.

public interface Product{

}
public class Pencil implements Product{

}

๐Ÿ‘‰ ๋‹ค์Œ์€ Store์™€ Pencil์ด ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์–ด ์žˆ๋Š” ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์™ธ๋ถ€์—์„œ ์ƒํ’ˆ์„ ์ฃผ์ž…(Injection)๋ฐ›์•„์•ผ ํ•œ๋‹ค.

public class Store{

   private Product product;

   public Store(Product product) {
      this.product = product;
   }

}

๐Ÿ‘‰ ์—ฌ๊ธฐ์„œ Spring์ด DI ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์šฐ์„  Store์—์„œ Product ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ์ ์— ํ•„์š”ํ•œ ๊ฐ์ฒด(๋นˆ)๋ฅผ ์ƒ์„ฑํ•ด์•ผํ•˜๋ฉฐ, ์˜์กด์„ฑ์ด ์žˆ๋Š” ๋‘ ๊ฐ์ฒด๋ฅผ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ•œ ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ์ฃผ์ž…์‹œ์ผœ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด Pencil์ด๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ ๊ฐ์ฒด๋ฅผ Store๋กœ ์ฃผ์ž…์‹œ์ผœ์ฃผ๋Š” ์—ญํ• ์„ ์œ„ํ•ด DI ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํ•„์š”ํ•˜๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค.

public class BeanFactory{

    public void store() {
      
      //Bean์˜ ์ƒ์„ฑ
      Product pencil = new Pencil();    
      
      //์˜์กด์„ฑ ์ฃผ์ž…
      Store store = new Store(pencil);      

    }
}

๐Ÿ‘‰ ๊ทธ๋ฆฌ๊ณ  ์ด๋Ÿฌํ•œ ๊ฐœ๋…์€ ์ œ์–ด์˜ ์—ญ์ „(Inversion of Control, IoC)๋ผ๊ณ  ๋ถˆ๋ฆฌ๊ธฐ๋„ ํ•œ๋‹ค. ์–ด๋– ํ•œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ• ์ง€์— ๋Œ€ํ•œ ์ฑ…์ž„์ด BeanFactory์™€ ๊ฐ™์€ ํด๋ž˜์Šค์—๊ฒŒ ๋„˜์–ด๊ฐ”๊ณ , ์ž์‹ ์€ ์ˆ˜๋™์ ์œผ๋กœ ์ฃผ์ž…๋ฐ›๋Š” ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (์‹ค์ œ Spring์—์„œ๋Š” BeanFactory๋ฅผ ํ™•์žฅํ•œ Application Context๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.)


๐Ÿ“Œ 3. ๋‹ค์–‘ํ•œ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐฉ๋ฒ•


๐Ÿ“Ž @Autowired๋ž€?

@Autowired๋Š” ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Annotation์œผ๋กœ ์ƒ์„ฑ์ž๋‚˜ ์„ธํ„ฐ ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•˜๋ ค๊ณ  ํ•  ๋•Œ, ํ•ด๋‹น ๋นˆ์„ ์ฐพ์•„์„œ ์ฃผ์ž…ํ•ด์ค€๋‹ค. ๋˜ํ•œ, ์˜์กด ๊ฐ์ฒด(Bean)๊ฐ€ 2๊ฐœ ์ด์ƒ์ด๋ฉด ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. @Autowired๋ฅผ ํ†ตํ•ด ์˜์กด์„ฑ ์ฃผ์ž…์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, 4๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ“Ž ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐฉ๋ฒ• (1): ์ƒ์„ฑ์ž ์ฃผ์ž…(Constructor Injection)

๐Ÿ‘‰ ์ƒ์„ฑ์ž ์ฃผ์ž…์€ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์˜์กด ๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

@Service
public class UserServiceImpl implements UserService{

   private UserRepository userRepository;
   private MemberService memberService;

   @Autowired
   public UserServiceImpl(UserRepository userRepository, MemberService memberService) {
     this.userRepository = userRepository;
     this.memberService = memberService;
   }

}

๐Ÿ‘‰ ์ƒ์„ฑ์ž ์ฃผ์ž…์€ ์ƒ์„ฑ์ž์˜ ํ˜ธ์ถœ ์‹œ์ ์— 1ํšŒ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์ž…๋ฐ›์€ ๊ฐ์ฒด๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜, ๋ฐ˜๋“œ์‹œ ๊ฐ์ฒด์˜ ์ฃผ์ž…์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ๊ฐ•์ œํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ Spring ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์ ๊ทน ์ง€์›ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ƒ์„ฑ์ž๊ฐ€ 1๊ฐœ๋งŒ ์žˆ์„ ๊ฒฝ์šฐ์— @Autowired๋ฅผ ์ƒ๋žตํ•ด๋„ ์ฃผ์ž…์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ํŽธ์˜์„ฑ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์œ„์˜ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๋™์ผํ•œ ์ฝ”๋“œ๊ฐ€ ๋œ๋‹ค.

@Service
public class UserServiceImpl implements UserService{

   private UserRepository userRepository;
   private MemberService memberService;

   public UserServiceImpl(UserRepository userRepository, MemberService memberService) {
     this.userRepository = userRepository;
     this.memberService = memberService;
   }

}

๐Ÿ“Ž ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐฉ๋ฒ• (2): ์ˆ˜์ •์ž ์ฃผ์ž…(Setter ์ฃผ์ž…, Setter Injection)

๐Ÿ‘‰ ์ˆ˜์ •์ž์ฃผ์ž…์€ ํ•„๋“œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” Setter๋ฅผ ํ†ตํ•ด์„œ ์˜์กด ๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. Setter ์ฃผ์ž…์€ ์ƒ์„ฑ์ž ์ฃผ์ž…๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ฃผ์ž…๋ฐ›๋Š” ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•œ๋‹ค. (์‹ค์ œ๋กœ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋Š” ๊ทนํžˆ ๋“œ๋ฌผ๋‹ค.) @Autowired๋กœ ์ฃผ์ž…ํ•  ๋Œ€์ƒ์ด ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์•„๋ž˜ ์˜ˆ์ œ์—์„œ๋Š” XXX ๋นˆ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ฃผ์ž…ํ•  ๋Œ€์ƒ์ด ์—†์–ด๋„ ๋™์ž‘ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด @Autowired(required = false)๋ฅผ ํ†ตํ•ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

@Service
public class UserServiceImpl implements UserService{

   private UserRepository userRepository;
   private MemberService memberService;
   
   @Autowired
   public void setUserRepository(UserRepository userRepository) {
     this.userRepository = userRepository;
   }

   @Autowired
   public void setMemberService(MemberService memberSerive) {
      this.memberService = memberService;
   }

}

๐Ÿ“Ž ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐฉ๋ฒ• (3): ํ•„๋“œ ์ฃผ์ž…(Field Injection)

๐Ÿ‘‰ ํ•„๋“œ์ฃผ์ž…์€ ํ•„๋“œ์— ๋ฐ”๋กœ ์˜์กด ๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. IntelliJ์—์„œ ํ•„๋“œ ์ธ์ ์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด Field Injection is not recommended์ด๋ผ๋Š” ๊ฒฝ๊ณ  ๋ฌธ๊ตฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

@Service
public class UserServiceImpl implements UserService{

   @Autowired
   private UserRepository userRepository;
   @Autowired
   private MemberService memberService;

}

๐Ÿ‘‰ ํ•„๋“œ ์ฃผ์ž…์„ ์ด์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ ธ์„œ ๊ณผ๊ฑฐ์— ์ƒ๋‹นํžˆ ๋งŽ์ด ์ด์šฉ๋˜์—ˆ๋˜ ์ฃผ์ž… ๋ฐฉ๋ฒ•์ด๋‹ค. ํ•˜์ง€๋งŒ ํ•„๋“œ ์ฃผ์ž…์€ ์™ธ๋ถ€์—์„œ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋‹จ์ ์ด ์กด์žฌํ•˜๋Š”๋ฐ, ์ ์ฐจ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ์ค‘์š”์„ฑ์ด ๋ถ€๊ฐ๋จ์— ๋”ฐ๋ผ ํ•„๋“œ์˜ ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋Š” ํ•„๋“œ ์ฃผ์ž…์€ ๊ฑฐ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ๋‹ค. ๋˜ํ•œ ํ•„๋“œ ์ฃผ์ž…์€ ๋ฐ˜๋“œ์‹œ DI ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉ์„ ์ง€์–‘ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— ์• ํ”Œ์ด์ผ€์ด์…˜์˜ ์‹ค์ œ ์ฝ”๋“œ์™€ ๋ฌด๊ด€ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋‚˜ ์„ค์ •์„ ์œ„ํ•ด ๋ถˆ๊ฐ€ํ”ผํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ด์šฉํ•˜๋„๋ก ํ•ด์•ผํ•œ๋‹ค.

๐Ÿ“Ž ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐฉ๋ฒ• (4): ์ผ๋ฐ˜ ๋ฉ”์†Œ๋“œ ์ฃผ์ž…(Method Injection)

๐Ÿ‘‰ ์ผ๋ฐ˜ ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์˜์กด ๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ํ•œ๋ฒˆ์— ์—ฌ๋Ÿฌ ํ•„๋“œ๋ฅผ ์ฃผ์ž… ๋ฐ›์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ฑฐ์˜ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ์ฃผ์ž… ๋ฐฉ๋ฒ•์ด๋‹ค.


๐Ÿ“Œ 4. ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ 


๐Ÿ“Ž ์ด์œ (1): ๊ฐ์ฒด์˜ ๋ถˆ๋ณ€์„ฑ ํ™•๋ณด

๐Ÿ‘‰ ์‹ค์ œ๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด, ์˜์กด ๊ด€๊ณ„ ์ฃผ์ž…์˜ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ์ƒํ™ฉ์€ ๊ฑฐ์˜ ์—†๋‹ค. ํ•˜์ง€๋งŒ ์ˆ˜์ •์ž ์ฃผ์ž…์ด๋‚˜ ์ผ๋ฐ˜ ๋ฉ”์†Œ๋“œ ์ฃผ์ž…์„ ์ด์šฉํ•˜๋ฉด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์ˆ˜์ •์˜ ๊ฐ€๋Šฅ์„ฑ์„ ์—ด์–ด๋‘๊ฒŒ ๋˜๋ฉฐ, ์ด๋Š” OOP์˜ 5๊ฐ€์ง€ ๊ฐœ๋ฐœ ์›์น™ ์ค‘ OCP(Open-Closed Principle, ๊ฐœ๋ฐฉ-ํ์‡„์˜๋ฒ•์น™)๋ฅผ ์œ„๋ฐ˜ํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ํ†ตํ•ด ๋ณ€๊ฒฝ์˜ ๊ฐ€๋Šฅ์„ฑ์„ ๋ฐฐ์ œํ•˜๊ณ  ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.


๐Ÿ“Ž ์ด์œ (2): ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ์ž‘์„ฑ

๐Ÿ‘‰ ์‹ค์ œ ์ฝ”๋“œ๊ฐ€ ํ•„๋“œ ์ฃผ์ž…์œผ๋กœ ์ž‘์„ฑ๋œ ๊ฒฝ์šฐ์—๋Š” ์ˆœ์ˆ˜ํ•œ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์€ ์‹ค์ œ ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค๊ณ  ํ•˜์ž.

@Service
public class UserServiceImpl implements UserService{

   @Autowired
   private UserRepository userRepository;
   @Autowired
   private MemberService memberService;

   @Override
   public void register(String name){
     userRepositoryadd(name);
   }

}

๐Ÿ‘‰ ์œ„์˜ ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ˆœ์ˆ˜ ์ž๋ฐ” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

public class UserServiceTest{

   @Test
   public void addTest(){
     UserService userService = new UserServiceImpl();
     userService.register("MinKyu");
   }

}

๐Ÿ‘‰ ์œ„์™€ ๊ฐ™์ด ์ž‘์„ฑํ•œ ์ˆœ์ˆ˜ ์ž๋ฐ” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” Spring๊ณผ ๊ฐ™์€ DI ํ”„๋ ˆ์ž„์›Œํฌ ์œ„์—์„œ ๋™์ž‘ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๊ณ , userRepository๊ฐ€ null์ด ๋˜์–ด userRepository์˜ add ํ˜ธ์ถœ ์‹œ NullPointExeption๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Setter๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ๊ธฐ๋ฐ˜์˜ ๋นˆ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ์น˜๋ช…์ ์ธ ๋‹จ์ ์„ ๊ฐ–๊ฒŒ๋œ๋‹ค.

๋˜ํ•œ ๋ฐ˜๋Œ€๋กœ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ๋„ @Autowired๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์Šคํ”„๋ง ๋นˆ์„ ์˜ฌ๋ฆฌ๋ฉด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๊ฐ€ ์•„๋‹ˆ๋ฉฐ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋“ฑ๋กํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์‹œ๊ฐ„์ด ์ปค์ ธ ํ…Œ์ŠคํŠธ ๋น„์šฉ์ด ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค.

๋ฐ˜๋ฉด์— ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ปดํŒŒ์ผ ์‹œ์ ์— ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…๋ฐ›์•„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ฃผ์ž…ํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ฌ์ง€์–ด ์šฐ๋ฆฌ๊ฐ€ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ๋งŒ๋“  Test๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์ž๋กœ ๋„ฃ์–ด ํŽธ๋ฆฌํ•จ์„ ์–ป์„ ์ˆ˜๋„ ์žˆ๋‹ค.

๐Ÿ“Ž ์ด์œ (3): final ํ‚ค์›Œ๋“œ ์ž‘์„ฑ ๋ฐ Lombok๊ณผ์˜ ๊ฒฐํ•ฉ

๐Ÿ‘‰ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•„๋“œ ๊ฐ์ฒด์— final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ปดํŒŒ์ผ ์‹œ์ ์— ๋ˆ„๋ฝ๋œ ์˜์กด์„ฑ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋ฉด์— ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์ œ์™ธํ•œ ๋‹ค๋ฅธ ์ฃผ์ž… ๋ฐฉ๋ฒ•๋“ค์€ ๊ฐ์ฒด์˜ ์ƒ์„ฑ(์ƒ์„ฑ์ž ํ˜ธ์ถœ) ์ดํ›„์— ํ˜ธ์ถœ๋˜๋ฏ€๋กœ final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

๋˜ํ•œ, final ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ž„์œผ๋กœ์จ Lombok๊ณผ ๊ฒฐํ•ฉ๋˜์–ด ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. Spring๊ณผ ๊ฐ™์€ DI ํ”„๋ ˆ์ž„์›Œํฌ๋Š” Lombok๊ณผ ํ™˜์ƒ์ ์ธ ๊ถํ•ฉ์„ ๋ณด์—ฌ์ฃผ๋Š”๋ฐ, ์œ„์—์„œ ์ž‘์„ฑํ–ˆ๋˜ ์ƒ์„ฑ์ž ์ฃผ์ž… ์ฝ”๋“œ๋ฅผ Lombok๊ณผ ๊ฒฐํ•ฉ์‹œํ‚ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„ํŽธํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ฝ”๋“œ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” Spring์—์„œ๋Š” ์ƒ์„ฑ์ž๊ฐ€ 1๊ฐœ์ธ ๊ฒฝ์šฐ @Autowired๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๊ณ  ์žˆ์œผ๋ฉฐ, ํ•ด๋‹น ์ƒ์„ฑ์ž๋ฅผ Lombok์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService{

    private final UserRepository userRepository;
    private final MemberService memberService;

    @Override
    public void register(String name){
      userRepository.add(name);
   }

}



๐Ÿ“– ์ฐธ๊ณ 

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