๋šœ๋ถ€๋‹ˆ์˜ Devlog

Spring DI

by ๋šœ๋ถ€๋‹ˆ

์Šคํ”„๋ง DI

Spring DI (Dependency Injection)

์Šคํ”„๋ง์—์„œ ์˜์กด์„ฑ ์ฃผ์ž…์€, ๊ฐ ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด์„ฑ์„ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ž๋™์œผ๋กœ ์—ฐ๊ฒฐํ•ด์คŒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์Šคํ”„๋ง DI๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

์˜ˆ๋ฅผ ๋“ค์–ด A ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ B ํด๋ž˜์Šค์™€ C ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•œ๋‹ค๊ณ  ํ•  ๋•Œ, ์•„๋ž˜์™€ ๊ฐ™์ด A ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ B ํด๋ž˜์Šค์™€ C ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด์„œ ์‚ฌ์šฉํ•˜๋„๋ก ๊ตฌ์„ฑํ–ˆ๋‹ค๊ณ  ํ•ฉ์‹œ๋‹ค.

public class A {
    private B b;
    private C c;
    
    public A() {
        b = new B();
        c = new C();
    }
}

์ด๋ ‡๊ฒŒ ์ƒ์„ฑํ•œ ๊ฒฝ์šฐ, B ํด๋ž˜์Šค๋‚˜ C ํด๋ž˜์Šค์— ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ๋ฐœ์ƒํ•˜๋ฉด, A ํด๋ž˜์Šค์— ์ˆ˜์ •์ด ํ•„์š”ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ฝ”๋“œ๋ฅผ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋†’์€ ์ฝ”๋“œ๋ผ๊ณ  ํ‘œํ˜„ํ•˜๋ฉฐ, A ํด๋ž˜์Šค๋Š” B ํด๋ž˜์Šค์™€ C ํด๋ž˜์Šค์— ์˜์กด์„ฑ์„ ๊ฐ€์ง„๋‹ค๊ณ  ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

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

public class A {
    @Autowired
    private B b;
    @Autowired
    private C c;
}

Spring DI ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

1. ํ•„๋“œ ์ฃผ์ž… (Field Injection)

ํ•„๋“œ ์ฃผ์ž…์€ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๊ณ  ์‹ถ์€ ํ•„๋“œ์— @Autowired ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์—ฌ์ฃผ๋ฉด ์˜์กด์„ฑ์ด ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค.

public class A {
    @Autowired
    private B b;
    @Autowired
    private C c;
}

ํŠน์ง•

  • ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
  • ํ•„๋“œ์— final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์–ด ๋ถˆ๋ณ€์„ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ๋ธ”๋กœ๊ทธ๋ฅผ ์ฝ์–ด๋ณด๋ฉด SRP ์œ„๋ฐ˜์ด๋‚˜ ๋ณด์ด์ง€ ์•Š๋Š” ์˜์กด์„ฑ์— ๋Œ€ํ•ด ๋‚˜์˜ค๋Š”๋ฐ, ์•„๋ž˜ ๋งํฌ๋ฅผ ๊ฑธ์–ด๋‘” ๋ธ”๋กœ๊ทธ๋ฅผ ์ฝ์–ด๋ณด๋ฉด ์ด๋Š” ํ•„๋“œ ์ฃผ์ž…๋งŒ์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์–ด ํŠน์ง•์—์„œ ์ œ์™ธํ–ˆ์Šต๋‹ˆ๋‹ค.

[Spring] DI(Dependency Injection) ์ •๋ฆฌ 

์ฐธ๊ณ ๋กœ, ์ธํ…”๋ฆฌ์ œ์ด์—์„œ ํ•„๋“œ ์ฃผ์ž… ์‚ฌ์šฉ ์‹œ ๊ฒฝ๊ณ ์ฐฝ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

๋นˆ์„ ์ฃผ์ž…ํ•˜๋Š” ์ˆœ์„œ

  1. ์ฃผ์ž… ๋ฐ›์œผ๋ ค๋Š” ๋นˆ์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋นˆ์„ ์ฐพ๊ฑฐ๋‚˜ ๋นˆ ํŒฉํ† ๋ฆฌ์— ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  2. ์ƒ์„ฑ์ž ์ธ์ž์— ์‚ฌ์šฉํ•˜๋Š” ๋นˆ์„ ์ฐพ๊ฑฐ๋‚˜ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. ํ•„๋“œ์— ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.

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

public class App {
    public static void main(String[] args) {
        A a = new A(); // ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์ปดํŒŒ์ผ ์—๋Ÿฌ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
    }
}

2. ์ˆ˜์ •์ž ์ฃผ์ž… (Setter Based Injection)

์ˆ˜์ •์ž ์ฃผ์ž…์€ setter ๋ฉ”์„œ๋“œ์— @Autowired ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์—ฌ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์„ ํƒ, ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ์˜์กด๊ด€๊ณ„์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์ข‹์œผ๋ฉฐ, ์ž๋ฐ” ๋นˆ ํ”„๋กœํผํ‹ฐ ๊ทœ์•ฝ์˜ ์ˆ˜์ •์ž ๋ฉ”์„œ๋“œ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

public class A {
    private B b;
    private C c;
    
    @Autowired
    public void setB(B b) {
        this.b = b;
    }

    @Autowired
    public void setC(C c) {
        this.c = c;
    }
}

ํŠน์ง•

  • ์„ ํƒ, ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ์˜์กด๊ด€๊ณ„์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
  • ์ž๋ฐ”๋นˆ ํ”„๋กœํผํ‹ฐ ๊ทœ์•ฝ์˜ ์ˆ˜์ •์ž ๋ฉ”์„œ๋“œ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. (setXxx)
  • ํ•„๋“œ์— final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์–ด ๋ถˆ๋ณ€์„ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์„ ํƒ์ ์œผ๋กœ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ˆ„๋ฝ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฉฐ, ๋ˆ„๋ฝ ์‹œ NPE ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋นˆ์„ ์ฃผ์ž…ํ•˜๋Š” ์ˆœ์„œ

  1. ์ฃผ์ž… ๋ฐ›์œผ๋ ค๋Š” ๋นˆ์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋นˆ์„ ์ฐพ๊ฑฐ๋‚˜ ๋นˆ ํŒฉํ† ๋ฆฌ์— ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  2. ์ƒ์„ฑ์ž ์ธ์ž์— ์‚ฌ์šฉํ•˜๋Š” ๋นˆ์„ ์ฐพ๊ฑฐ๋‚˜ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. ์ฃผ์ž…ํ•˜๋ ค๋Š” ๋นˆ ๊ฐ์ฒด์˜ ์ˆ˜์ •์ž๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.

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

public class App {
    public static void main(String[] args) {
        A a = new A(); // ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์ปดํŒŒ์ผ ์—๋Ÿฌ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
    }
}

3. ์ƒ์„ฑ์ž ์ฃผ์ž… (Constructor Based Injection)

์ƒ์„ฑ์ž ์ฃผ์ž…์€ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

public class A {
    private final B b;
    private final C c;
    @Autowired // ์ƒ์„ฑ์ž๊ฐ€ ๋”ฑ ํ•˜๋‚˜๋งŒ ์กด์žฌํ•˜๋ฉด, @Autowired ๋ฅผ ์ƒ๋žตํ•ด๋„ ์ž๋™ ์ฃผ์ž…๋œ๋‹ค.
    public A(B b, C c) {
        this.b = b;
        this.c = c;
    }
}

๋˜ํ•œ, Lombok ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” @RequiredArgsConstructor ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด final ์ด ๋ถ™์€ ํ•„๋“œ๋ฅผ ๋ชจ์•„์„œ ์ƒ์„ฑ์ž๋ฅผ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์—, ํ•„๋“œ ์ฃผ์ž…์ฒ˜๋Ÿผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@RequiredArgsConstructor
public class A {
    private final B b;
    private final C c;
}

ํŠน์ง•

  • ํ•„๋“œ์— final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ๋ถˆ๋ณ€์„ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.(๊ฐ์ฒด ์ƒ์„ฑ ์‹œ ๋”ฑ 1๋ฒˆ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ ์ดํ›„ ๋ณ€๊ฒฝ๋  ์ผ X)
  • ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์‹œ์ ์— ๋นˆ์„ ์ฃผ์ž…ํ•˜๊ธฐ ๋•Œ๋ฌธ์— NPE ๋ฐœ์ƒ์„ ๋ง‰์Šต๋‹ˆ๋‹ค.

๋นˆ์„ ์ฃผ์ž…ํ•˜๋Š” ์ˆœ์„œ

  1. ์ƒ์„ฑ์ž์˜ ์ธ์ž์— ์‚ฌ์šฉ๋˜๋Š” ๋นˆ์„ ์ฐพ๊ฑฐ๋‚˜ ๋นˆ ํŒฉํ† ๋ฆฌ์—์„œ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ์ฐพ์€ ์ธ์ž ๋นˆ์œผ๋กœ ์ฃผ์ž…ํ•˜๋ ค๋Š” ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

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

public class App {
    public static void main(String[] args) {
        // AS-IS : ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜์ง€ ์•Š์•„ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ
        A a = new A();    }
}

public class App {
    public static void main(String[] args) {
        // TO-BE : ์˜์กด์„ฑ ์ฃผ์ž…
        B b = new B();
        C c = new C();
        A a = new A(b, c);
    }
}

๐Ÿ”— ์ฐธ๊ณ 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

๋šœ๋ถ€๋‹ˆ์˜ Devlog

๋šœ๋ถ€๋‹ˆ

ํ™œ๋™ํ•˜๊ธฐ