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

WINK-(Web & App)/Spring Boot ์Šคํ„ฐ๋””

[2025 1ํ•™๊ธฐ ์Šคํ”„๋ง๋ถ€ํŠธ ์Šคํ„ฐ๋””] ์„์ค€ํ™˜ #1์ฃผ์ฐจ

๋ฐ˜์‘ํ˜•

๐Ÿš€ ์Šคํ”„๋ง์ด๋ž€?

1. DI container ๊ธฐ์ˆ ?

์Šคํ”„๋ง ๋นˆ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ์ˆ 

2.์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ?

3.์Šคํ”„๋ง ๋ถ€ํŠธ, ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ ๋“ฑ์„ ๋ชจ๋‘ ํฌํ•จํ•œ ์Šคํ”„๋ง ์ƒํƒœ๊ณ„

 

ํ•ต์‹ฌ์€ ์ข‹์€ ๊ฐ์ฒด ์ง€ํ–ฅ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ผ๋Š” ์ ์ด๋‹ค

 

๐Ÿš€ ์ข‹์€ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ž€?

๊ฐ์ฒด ์ง€ํ–ฅ์˜ ํŠน์„ฑ

1. ์ถ”์ƒํ™”

2.์บก์Аํ™”

3.์ƒ์†

4.๋‹คํ˜•์„ฑ

 

๋Œ€๊ทœ๋ชจ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์—์„œ ๊ฒฐ๊ตญ ์ค‘์š”ํ•œ๊ฑด ๋‹คํ˜•์„ฑ

์œ ์—ฐํ•˜๊ฒŒ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค

์—ญํ• ๊ณผ ๊ตฌํ˜„์„ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋ณด์ž

์ž๋™์ฐจ์˜ ์—ญํ• ์„ ์„ธ๊ฐœ์˜ ์ž๋™์ฐจ์— ๋ถ€์—ฌ

k3 ํƒ€๋‹ค๊ฐ€ ์•„๋ฐ˜๋–ผ๋ฅผ ํƒ€๋„ ์šด์ „์„ ํ•  ์ˆ˜ ์žˆ๋‹ค

์šด์ „์ž์—๊ฒŒ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค

์ž๋™์ฐจ ์—ญํ• ์„ k3์—์„œ ํ…Œ์Šฌ๋ผ๋กœ ๋ฐ”๊ฟ”๋„ ์šด์ „์ž๋Š” ์šด์ „์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์™œ? ์ž๋™์ฐจ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ธฐ๋Šฅ์˜ ํฐ ๊ทธ๋ฆผ์€ ์งœ๋†จ๊ธฐ ๋•Œ๋ฌธ์—

 

ํด๋ผ์ด์–ธํŠธ๋Š” ๋‚ด๋ถ€ ๋™์ž‘์„ ๋ชฐ๋ผ๋„ ๋œ๋‹ค

์ž๋™์ฐจ ์„ธ์ƒ์„ ๋ฌดํ•œํžˆ ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๋‹ค!

 

 

์ •๋ฆฌ

์—ญํ• ๊ณผ ๊ตฌํ˜„์œผ๋กœ ๊ตฌ๋ถ„ํ•˜๋ฉด ์„ธ์ƒ์ด ๋‹จ์ˆœํ•ด์ง„๋‹ค

ํด๋ผ์ด์–ธํŠธ๋Š” ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ์ „ํ˜€ ๋ชฐ๋ผ๋„ ๋œ๋‹ค

๋Œ€์ƒ ์ž์ฒด๋ฅผ ๋ณ€๊ฒฝํ•ด๋„ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค ์™œ? ์—ญํ• ์€ ๊ทธ๋Œ€๋กœ๋‹ˆ๊น

๋‹คํ˜•์„ฑ

์—ญํ•  = ์ธํ„ฐํŽ˜์ด์Šค

๊ตฌํ˜„=๊ตฌํ˜„ ๊ฐ์ฒด ํด๋ž˜์Šค

์—ญํ• ๊ณผ ๊ตฌํ˜„์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•˜๊ณ 

๊ฐ์ฒด ํ˜‘๋ ฅ์ด๋ผ๋Š” ๊ด€๊ณ„๋ถ€ํ„ฐ ์ƒ๊ฐํ•˜์ž.

 

๋‹คํ˜•์„ฑ์˜ ๋ณธ์งˆ

์‹คํ–‰ ์‹œ์ ์— ์œ ์—ฐํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค

ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ์„œ๋ฒ„์˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์œ ์—ฐํ•˜๊ฒŒ ํ•˜๋Š”๊ฒƒ์ด ๋ณธ์งˆ์ด๋‹ค.

 

๐Ÿš€์ข‹์€ ๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„์˜ ๋ณธ์งˆ

1.SRP ์›์น™(Single Responsibility Principle) - ๋‹จ์ผ ์ฑ…์ž„ ์›์น™

ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋Š” ํ•˜๋‚˜์˜ ์ฑ…์ž„๋งŒ!!

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ๋งค์šฐ ๋ชจํ˜ธํ•จ

๊ทธ๋ž˜์„œ ์ค‘์š”ํ•œ ๊ธฐ์ค€์€ ๋ณ€๊ฒฝ์ด๋‹ค.

๋ณ€๊ฒฝํ•˜๊ธฐ ์‰ฝ๋„๋ก ํ•˜๋Š” ๊ฒฝ๊ณ„๊นŒ์ง€ ๋‹จ์ผ ์ฑ…์ž„์„ ๋ถ€์—ฌ

 

2.OCP(Open/Closed Principle) - ๊ฐœ๋ฐœ-ํ์‡„ ๋ฒ•์น™

๋งค์šฐ ์ค‘์š”!!

 

ํ™•์žฅ์—๋Š” ์—ด๋ ค ์žˆ์œผ๋‚˜ ๋ณ€๊ฒฝ์—๋Š” ๋‹ซํ˜€ ์žˆ์–ด์•ผ ํ•œ๋‹ค

์ด๊ฑฐ๋ฅผ DI์™€ IOC๋กœ ํ•ด์คŒ

์ฝ”๋“œ๋กœ ํ•ด๋ด์•ผ ์•Œ ์ˆ˜ ์žˆ๋‹ค

๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ๋งŒ ์ธ์ง€

 

3.LSP(Liskov Substitution Principle) ๋ฆฌ์Šค์ฝ”ํ”„ ์น˜ํ™˜ ์›์น™

์ž์‹ ํด๋ž˜์Šค๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ ๊ธฐ๋Œ€ํ•œ ๋™์ž‘์„ ๊ทธ๋Œ€๋กœ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ๊ทธ๋ณด๋‹ค ๋” ๋‚˜์€ ๋™์ž‘์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ ์ •์˜๋œ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋™์ž‘์„ ํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.

 

 

4.ISP(Interface Segregation Principle) - ์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ ์›์น™

๊ธฐ๋Šฅ์— ๋งž๊ฒŒ ์ž˜ ์ชผ๊ฐœ๋Š”๊ฒŒ ์ค‘์š”

์ฆ‰ ํ•˜๋‚˜์˜ ํฐ ์ธํ„ฐํŽ˜์ด์Šค๋ณด๋‹ค ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๋Š” ์›์น™์ž…๋‹ˆ๋‹ค.

 

 

5.DIP(Dependency Inversion Principle) - ์˜์กด ๊ด€๊ณ„ ์—ญ์ „ ์›์น™

๋งค์šฐ ์ค‘์š”!!

์ƒ์œ„ ๋ชจ๋“ˆ์ด ํ•˜์œ„ ๋ชจ๋“ˆ์— ์˜์กดํ•˜์ง€ ์•Š๊ณ , ํ•˜์œ„ ๋ชจ๋“ˆ์ด ์ƒ์œ„ ๋ชจ๋“ˆ์— ์˜์กดํ•˜์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์›์น™

 

์ถ”์ƒํ™”์— ์˜์กดํ•ด์•ผ์ง€ ๊ตฌ์ฒดํ™”์— ์˜์กดํ•˜๋ฉด ์•ˆ๋œ๋‹ค

์šด์ „์ž๋Š” k3์— ๋Œ€ํ•ด ๋””ํ…Œ์ผํ•˜๊ฒŒ ์•Œ ํ•„์š”๊ฐ€ ์—†๋‹ค ๊ทธ๋ƒฅ ์—ญํ• ๋งŒ ์•Œ๋ฉด๋œ๋‹ค

์ฆ‰ ์—ญํ• ์ด ์ค‘์š”ํ•˜๋‹ค ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ค‘์š”ํ•˜๋‹ค

์—ญํ• ์— ์˜์กดํ•ด์•ผ ๋œ๋‹ค ๊ตฌํ˜„์— ์˜์กดํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

 

class LightBulb {
    public void turnOn() {
        System.out.println("LightBulb turned on");
    }
    public void turnOff() {
        System.out.println("LightBulb turned off");
    }
}

class Switch {
    private LightBulb bulb;
    
    public Switch(LightBulb bulb) {
        this.bulb = bulb;
    }

    public void operate() {
        System.out.println("Switching...");
        bulb.turnOn();
    }
}

Switch๊ฐ€ LightBulb์— ์˜์กดํ•œ๋‹ค -->DIP ์œ„๋ฐ˜

 

 

interface Switchable {
    void turnOn();
    void turnOff();
}

class LightBulb implements Switchable {
    @Override
    public void turnOn() {
        System.out.println("LightBulb turned on");
    }

    @Override
    public void turnOff() {
        System.out.println("LightBulb turned off");
    }
}

class Fan implements Switchable {
    @Override
    public void turnOn() {
        System.out.println("Fan turned on");
    }

    @Override
    public void turnOff() {
        System.out.println("Fan turned off");
    }
}

class Switch {
    private Switchable device;

    public Switch(Switchable device) {
        this.device = device;
    }

    public void operate() {
        System.out.println("Switching...");
        device.turnOn();
    }
}

DIP๋ฅผ ์ž˜ ์ง€ํ‚จ ์˜ˆ์‹œ

 

๐Ÿš€Why Spring?

์˜์กด์„ฑ ์ฃผ์ž… (DI, Dependency Injection)

 

**DI (Dependency Injection)**๋Š” ๊ฐ์ฒด๋“ค์ด ์ž์‹ ์ด ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ์™ธ๋ถ€์—์„œ ์ฃผ์ž…๋ฐ›๋Š” ๋ฐฉ์‹์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ ์ฃผ์ž…์€ ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์˜์กด ๊ด€๊ณ„๋ฅผ ์™ธ๋ถ€์—์„œ ์„ค์ •ํ•ด์ฃผ๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

 

์ฆ‰, ํด๋ž˜์Šค๋‚˜ ๊ฐ์ฒด๊ฐ€ **ํ•„์š”ํ•œ ์˜์กด์„ฑ(Dependency)**์„ ์ง์ ‘ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , ์™ธ๋ถ€์—์„œ ์ฃผ์ž…(Injection) ๋ฐ›๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์€ ๊ฐ์ฒด๊ฐ€ ์ž์‹ ์„ ์ƒ์„ฑํ•˜๋Š” ์ฑ…์ž„์„ ์ง€์ง€ ์•Š๊ณ , ์˜์กด์„ฑ์„ ์™ธ๋ถ€์—์„œ ์ฃผ์ž…๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ , ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ์„ฑ์„ ๋†’์ด๊ณ ,

ํ…Œ์ŠคํŠธ๊ฐ€ ์šฉ์ดํ•ด์ง‘๋‹ˆ๋‹ค.

 

DI์˜ ์ฃผ์š” ์ด์ :

 ๊ฒฐํ•ฉ๋„ ๊ฐ์†Œ: ๊ฐ์ฒด๊ฐ€ ์ง์ ‘ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์˜์กด์„ฑ์„ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ๊ฐ ๊ฐ์ฒด์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„์ง‘๋‹ˆ๋‹ค. ์ด๋Š” ์œ ์ง€๋ณด์ˆ˜์™€ ํ™•์žฅ์— ์œ ๋ฆฌํ•œ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

 ์œ ์—ฐ์„ฑ: ์˜์กด์„ฑ์˜ ๊ต์ฒด๊ฐ€ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํŠน์ • ํด๋ž˜์Šค์˜ ์˜์กด์„ฑ์„ ๊ต์ฒดํ•˜๊ณ ์ž ํ•  ๋•Œ, ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ๊ตฌํ˜„์„ ์ฃผ์ž…๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ: DI๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Mock ๊ฐ์ฒด๋‚˜ Stub ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ์œ ๋‹› ํ…Œ์ŠคํŠธ๋ฅผ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ฆ‰ ์ž๋™์ฐจ ๋ถ€ํ’ˆ ๊ต์ฒดํ•˜๋“ฏ์ด  ๊ฐ์ฒด ์ง€ํ–ฅ ์›์น™์„ ์ž˜ ์ง€ํ‚ค๋ฉฐ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๊ธฐ ๋•Œ๋ฌธ์— Spring์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ!

๋ฐ˜์‘ํ˜•