Spring/Spring ๊ธฐ๋ณธ

[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] - 15. ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ

hello_u 2023. 2. 4. 17:45

 

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์‹ฑ๊ธ€ํ†ค

 

๋‹ค์ˆ˜์˜ ๊ณ ๊ฐ ๋™์‹œ ์š”์ฒญ

 

๋Œ€๋ถ€๋ถ„์˜ ์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‹ค


์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ณดํ†ต ์—ฌ๋Ÿฌ ๊ณ ๊ฐ์ด ๋™์‹œ์— ์š”์ฒญ์„ ํ•œ๋‹ค.

 

@Test
@DisplayName("์Šคํ”„๋ง ์—†๋Š” ์ˆœ์ˆ˜ํ•œ DI ์ปจํ…Œ์ด๋„ˆ")
void pureContainer() {
    AppConfig appConfig = new AppConfig();

    // 1. ์กฐํšŒ : ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
    MemberService memberService1 = appConfig.memberService();

    // 2. ์กฐํšŒ : ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
    MemberService memberService2 = appConfig.memberService();

 

AppConfig๋Š” ์š”์ฒญ์„ ํ•  ๋•Œ ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•œ๋‹ค.

 

// ์ฐธ์กฐ๊ฐ’์ด ๋‹ค๋ฅธ ๊ฒƒ์„ ํ™•์ธ
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);

//memberService1 != memberService2
assertThat(memberService1).isNotSameAs(memberService2);

 

 

์ฐธ์กฐ๊ฐ’์ด ๋‹ค๋ฅธ ๊ฒƒ์„ ํ™•์ธ

 

๊ณ ๊ฐ ํŠธ๋ž˜ํ”ฝ์ด ์ดˆ๋‹น 100์ด ๋‚˜์˜ค๋ฉด ์ดˆ๋‹น 100๊ฐœ ์ด์ƒ์˜ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์†Œ๋ฉธ๋œ๋‹ค! ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๊ฐ€ ์‹ฌํ•˜๋‹ค.

 

ํ•ด๊ฒฐ๋ฐฉ์•ˆ์€ ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ๋”ฑ 1๊ฐœ๋งŒ ์ƒ์„ฑ๋˜๊ณ , ๊ณต์œ ํ•˜๋„๋ก ์„ค๊ณ„ํ•˜๋ฉด ๋œ๋‹ค. ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด

 

 

์‹ฑ๊ธ€ํ†ค ํŒจํ„ด

 

ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋”ฑ 1๊ฐœ๋งŒ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.

๊ทธ๋ž˜์„œ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ 2๊ฐœ ์ด์ƒ ์ƒ์„ฑํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰์•„์•ผ ํ•œ๋‹ค.

 

 

public class SingletonService {
    
    private static final SingletonService instance = new SingletonService();
}

 

static : ์ •์  ๋ณ€์ˆ˜๋Š” ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•˜๋‚˜์˜ ์ €์žฅ๊ณต๊ฐ„์„ ๊ณต์œ ํ•˜๊ธฐ์— ํ•ญ์ƒ ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค

 

private ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์™ธ๋ถ€์—์„œ ์ž„์˜๋กœ new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰์•„์•ผ ํ•œ๋‹ค.

 

static ๋ณ€์ˆ˜

๋”๋ณด๊ธฐ

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ HouseLee ํด๋ž˜์Šค๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์ž.

class HouseLee {
    String lastname = "์ด";
}

public class Sample {
    public static void main(String[] args) {
        HouseLee lee1 = new HouseLee();
        HouseLee lee2 = new HouseLee();
    }
}

 

์œ„์™€ ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ๊ฐ์ฒด๋งˆ๋‹ค ๊ฐ์ฒด๋ณ€์ˆ˜ lastname์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ณ„๋„๋กœ ํ• ๋‹น๋œ๋‹ค.

ํ•˜์ง€๋งŒ ๊ฐ€๋งŒํžˆ ์ƒ๊ฐํ•ด ๋ณด๋ฉด HouseLee ํด๋ž˜์Šค์˜ lastname์€ ์–ด๋–ค ๊ฐ์ฒด์ด๋˜์ง€ ๋™์ผํ•œ ๊ฐ’์ธ "์ด" ์ด์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์ง€ ์•Š์€๊ฐ€?

์ด๋ ‡๊ฒŒ ํ•ญ์ƒ ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด static ์‚ฌ์šฉ์‹œ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

class HouseLee {
    static String lastname = "์ด";
}

 

lastname ๋ณ€์ˆ˜์— static ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ด๋ฉด ์ž๋ฐ”๋Š” ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ๋”ฑ ํ•œ๋ฒˆ๋งŒ ํ•˜๊ฒŒ ๋˜์–ด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์— ์ด์ ์ด ์žˆ๋‹ค.

 

static์„ ์‚ฌ์šฉํ•˜๋Š” ๋˜ ํ•œ๊ฐ€์ง€ ์ด์œ ๋กœ ๊ณต์œ  ๊ฐœ๋…์„ ๋“ค ์ˆ˜ ์žˆ๋‹ค.

static ์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ๊ฐ™์€ ๊ณณ์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋งŒ์„ ๋ฐ”๋ผ๋ณด๊ธฐ ๋•Œ๋ฌธ์— static ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ๊ณต์œ ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

 

 

private static final SingletonService instance = new SingletonService();

 

1. static ์˜์—ญ์— ๊ฐ์ฒด instance๋ฅผ ๋ฏธ๋ฆฌ ํ•˜๋‚˜ ์ƒ์„ฑํ•ด์„œ ์˜ฌ๋ ค๋‘”๋‹ค.

 

์™ธ๋ถ€์—์„œ๋Š” ์ƒ์„ฑํ•ด ๋†“์€๊ฒƒ์„ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š”๊ฒƒ์ด๋‹ค ( getInstance() )

 

์ฐธ๊ณ : ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘๋Š” ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๊ณ  ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•์„ ์„ ํƒํ–ˆ๋‹ค.

 

 

public static SingletonService getInstance() {
    return instance;


2.
์ด ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”ํ•˜๋ฉด ์˜ค์ง getInstance() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ•ญ์ƒ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (static)

 

 

 

void singletonServiceTest() {
    new SingletonService();
}

 

private access / ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ ๋ถˆ๊ฐ€


3.
๋”ฑ 1๊ฐœ์˜ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋งŒ ์กด์žฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ์ƒ์„ฑ์ž๋ฅผ private์œผ๋กœ ๋ง‰์•„์„œ

ํ˜น์‹œ๋ผ๋„ ์™ธ๋ถ€์—์„œ new ํ‚ค์›Œ๋“œ๋กœ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š”๋‹ค.

 

 

 

์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

 

@Test
@DisplayName("์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์ ์šฉํ•œ ๊ฐ์ฒด ์‚ฌ์šฉ")
void singletonServiceTest() {
    SingletonService singletonService1 = SingletonService.getInstance();
    SingletonService singletonService2 = SingletonService.getInstance();

 

getInstance() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ์กฐํšŒ

 

 

//์ฐธ์กฐ๊ฐ’ ํ™•์ธ
System.out.println("singletonService1 = " + singletonService1);
System.out.println("singletonService2 = " + singletonService2);

assertThat(singletonService1).isSameAs(singletonService2);

isSameAs : ๋ฉ”๋ชจ๋ฆฌ์ƒ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š”์ง€ ๋น„๊ต (์ฃผ์†Œ ๋น„๊ต)


isEqualTo : ๊ฐ์ฒด๊ฐ€ ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ๋น„๊ตํ•œ๋‹ค.

 

 

ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š”์ง€ ํ™•์ธ ํ•ด๋ณด์ž .

 

์ฐธ์กฐ๊ฐ’์„ ํ™•์ธํ•˜์—ฌ ๋น„๊ตํ•œ๋‹ค .  

 

์ฐธ์กฐ๊ฐ’์ด ๊ฐ™์€ ๊ฒƒ์„ ํ™•์ธ

 

์ฐธ์กฐ๊ฐ’์ด ๊ฐ™๋‹ค. 

 

๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค .

 

์ด๋ฏธ ์ƒ์„ฑํ•ด ๋†“์€๊ฒƒ์„ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š”๊ฒƒ์ด๋‹ค .

 

 

 

์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ๋ฌธ์ œ์ 

 

public class SingletonService {

    private static final SingletonService instance = new SingletonService();

    public static SingletonService getInstance() {
        return instance;
    }

    private SingletonService() {
    }

 

  • ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฝ”๋“œ ์ž์ฒด๊ฐ€ ๋งŽ์ด ๋“ค์–ด๊ฐ„๋‹ค.
  •  ์˜์กด๊ด€๊ณ„์ƒ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ตฌ์ฒด ํด๋ž˜์Šค์— ์˜์กดํ•œ๋‹ค. DIP๋ฅผ ์œ„๋ฐ˜ํ•œ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ตฌ์ฒด ํด๋ž˜์Šค์— ์˜์กดํ•ด์„œ OCP ์›์น™์„ ์œ„๋ฐ˜ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค. ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
  • private ์ƒ์„ฑ์ž๋กœ ์ž์‹ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์–ด๋ ต๋‹ค.
  • ๊ฒฐ๋ก ์ ์œผ๋กœ ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.
  • ์•ˆํ‹ฐํŒจํ„ด์œผ๋กœ ๋ถˆ๋ฆฌ๊ธฐ๋„ ํ•œ๋‹ค.
  • ๋‚ด๋ถ€ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์ดˆ๊ธฐํ™” ํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

 

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ(์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ)๋Š” ์ด ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์˜ ๋ฌธ์ œ์ ์„ ์ „๋ถ€๋‹ค ํ•ด๊ฒฐํ•˜๊ณ  ๊ด€๋ฆฌํ•ด์ค€๋‹ค .

 

 

 

 

์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ

 

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์˜ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๋ฉด์„œ, ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ์‹ฑ๊ธ€ํ†ค(1๊ฐœ๋งŒ ์ƒ์„ฑ)์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

 

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์„ ์ ์šฉํ•˜์ง€ ์•Š์•„๋„, ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

 


์ด์ „์— ์„ค๋ช…ํ•œ ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ ๊ณผ์ •์„ ์ž์„ธํžˆ ๋ณด์ž.

 

 

 

์ปจํ…Œ์ด๋„ˆ๋Š” ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•ด์„œ ๊ด€๋ฆฌํ•œ๋‹ค.

 

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ์„ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‹ฑ๊ธ€ํ†ค ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ผ ํ•œ๋‹ค.

 

public class SingletonService {

    private static final SingletonService instance = new SingletonService();

    public static SingletonService getInstance() {
        return instance;
    }

    private SingletonService() {
    }

 

 ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์œ„ํ•œ  ์ด๋Ÿฐ ์ง€์ €๋ถ„ํ•œ ์ฝ”๋“œ๊ฐ€ ๋“ค์–ด๊ฐ€์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

 

DIP, OCP, ํ…Œ์ŠคํŠธ, private ์ƒ์„ฑ์ž๋กœ ๋ถ€ํ„ฐ ์ž์œ ๋กญ๊ฒŒ ์‹ฑ๊ธ€ํ†ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

 

@Test
@DisplayName("์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ์‹ฑ๊ธ€ํ†ค")
void springContainer() {
    
    ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

 

AppConfig ์„ค์ •ํŒŒ์ผ์„ ๊ตฌ์„ฑ์ •๋ณด๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ  

 

 

 

MemberService memberService1 = ac.getBean("memberService",MemberService.class);
MemberService memberService2 = ac.getBean("memberService",MemberService.class);

 

ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜

 

์Šคํ”„๋ง์ด  ์ปจํ…Œ์ด๋„ˆ์—์„œ  ์ฒ˜์Œ์— ๋“ฑ๋กํ•œ ๋นˆ์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค ( ์‹ฑ๊ธ€ํ†ค )

 

System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);

//memberService1 == memberService2
assertThat(memberService1).isSameAs(memberService2);

 

์ฐธ์กฐ ๊ฐ’์ด ๊ฐ™์€ ๊ฒƒ์„ ํ™•์ธ  

 

์ฐธ์กฐ๊ฐ’์ด ๊ฐ™์€ ๊ฒƒ์„ ํ™•์ธ

 

 

์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ ์ ์šฉ ํ›„

 

 

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ๋•๋ถ„์— ๊ณ ๊ฐ์˜ ์š”์ฒญ์ด ์˜ฌ ๋•Œ ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ,

์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•ด์„œ ํšจ์œจ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

์ฐธ๊ณ : ์Šคํ”„๋ง์˜ ๊ธฐ๋ณธ ๋นˆ ๋“ฑ๋ก ๋ฐฉ์‹์€ ์‹ฑ๊ธ€ํ†ค์ด์ง€๋งŒ, ์‹ฑ๊ธ€ํ†ค ๋ฐฉ์‹๋งŒ ์ง€์›ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

์š”์ฒญํ•  ๋•Œ ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ๋„ ์ œ๊ณตํ•œ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋’ค์— ๋นˆ ์Šค์ฝ”ํ”„์—์„œ ์„ค๋ช…ํ•˜๊ฒ ๋‹ค.

 

 

์‹ฑ๊ธ€ํ†ค ๋ฐฉ์‹์˜ ์ฃผ์˜์ 

 

์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์ด๋“ , ์Šคํ”„๋ง ๊ฐ™์€ ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜๋“ , ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•ด์„œ ๊ณต์œ ํ•˜๋Š” ์‹ฑ๊ธ€ํ†ค ๋ฐฉ์‹์€

์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•˜๋‚˜์˜ ๊ฐ™์€ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋Š” ์ƒํƒœ๋ฅผ ์œ ์ง€(stateful)ํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜๋ฉด ์•ˆ๋œ๋‹ค.


๋ฌด์ƒํƒœ(stateless)๋กœ ์„ค๊ณ„ํ•ด์•ผ ํ•œ๋‹ค!

 

ํŠน์ • ํด๋ผ์ด์–ธํŠธ์— ์˜์กด์ ์ธ ํ•„๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์•ˆ๋œ๋‹ค.


ํŠน์ • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ํ•„๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์•ˆ๋œ๋‹ค!


๊ฐ€๊ธ‰์  ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค. ( ์ˆ˜์ •X)


ํ•„๋“œ ๋Œ€์‹ ์— ์ž๋ฐ”์—์„œ ๊ณต์œ ๋˜์ง€ ์•Š๋Š”, ์ง€์—ญ๋ณ€์ˆ˜, ํŒŒ๋ผ๋ฏธํ„ฐ, ThreadLocal ๋“ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

์Šคํ”„๋ง ๋นˆ์˜ ํ•„๋“œ์— ๊ณต์œ  ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด ์ •๋ง ํฐ ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค!!!

 

 

 

 

์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ๊ฒฝ์šฐ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์  ์˜ˆ์‹œ

 

public class StatefulService {
    private int price;  // ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋Š” ํ•„๋“œ

    public void order(String name, int price) {
        System.out.println("name = " + name + " price = " + price);
        this.price = price;   //์—ฌ๊ธฐ๊ฐ€ ๋ฌธ์ œ!
    }

    public int getPrice() {
        return price;
    }
}

 

StatefulService ์˜ price ํ•„๋“œ๋Š” ๊ณต์œ ๋˜๋Š” ํ•„๋“œ์ธ๋ฐ, ํŠน์ • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•œ๋‹ค.

 

class StatefulServiceTest {

    @Test
    void statefulServiceSingleton() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
        StatefulService statefulService1 = ac.getBean(StatefulService.class);
        StatefulService statefulService2 = ac.getBean(StatefulService.class);

ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜

 

์Šคํ”„๋ง์ด  ์ปจํ…Œ์ด๋„ˆ์—์„œ  ์ฒ˜์Œ์— ๋“ฑ๋กํ•œ ๋นˆ์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค ( ์‹ฑ๊ธ€ํ†ค )

 

// ThreadA : A ์‚ฌ์šฉ์ž 10000์› ์ฃผ๋ฌธ
statefulService1.order("userA", 10000);
// ThreadB : B ์‚ฌ์šฉ์ž 20000์› ์ฃผ๋ฌธ
statefulService2.order("userB", 20000);

// ThreadA : A ์‚ฌ์šฉ์ž ์ฃผ๋ฌธ ๊ธˆ์•ก ์กฐํšŒ
int price = statefulService1.getPrice();
System.out.println("price = " + price);

ThreadA๊ฐ€ ์‚ฌ์šฉ์žA ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ThreadB๊ฐ€ ์‚ฌ์šฉ์žB ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค ๊ฐ€์ •ํ•˜์ž.

 

์‚ฌ์šฉ์žA์˜ ์ฃผ๋ฌธ๊ธˆ์•ก์€ 10000์›์ด ๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, 20000์›์ด๋ผ๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™”๋‹ค.

 

A ์‚ฌ์šฉ์ž ์ฃผ๋ฌธ ๊ธˆ์•ก ์กฐํšŒ

 

 

 

ํ•„๋“œ ๋Œ€์‹ ์— ์ž๋ฐ”์—์„œ ๊ณต์œ ๋˜์ง€ ์•Š๋Š”์ง€์—ญ๋ณ€์ˆ˜ํŒŒ๋ผ๋ฏธํ„ฐ, ThreadLocal ๋“ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

 

public class StatefulService {
    
    public int order(String name, int price) {
        System.out.println("name = " + name + " price = " + price);
        return price;
    }
}

 

์ง€์—ญ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉ 

 

// ThreadA : A ์‚ฌ์šฉ์ž 10000์› ์ฃผ๋ฌธ
int userAPrice = statefulService1.order("userA", 10000);
// ThreadB : B ์‚ฌ์šฉ์ž 20000์› ์ฃผ๋ฌธ
int userBPrice = statefulService2.order("userB", 20000);

// ThreadA : A ์‚ฌ์šฉ์ž ์ฃผ๋ฌธ ๊ธˆ์•ก ์กฐํšŒ
System.out.println("price = " + userAPrice);

 

 

 

 

 

์ง„์งœ ๊ณต์œ ํ•„๋“œ๋Š” ์กฐ์‹ฌํ•ด์•ผ ํ•œ๋‹ค! ์Šคํ”„๋ง ๋นˆ์€ ํ•ญ์ƒ ๋ฌด์ƒํƒœ(stateless)๋กœ ์„ค๊ณ„ํ•˜์ž.

 

 

 

 

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

 

์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

์Šคํ”„๋ง ์ž…๋ฌธ์ž๊ฐ€ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์–ด๊ฐ€๋ฉด์„œ ์Šคํ”„๋ง์˜ ํ•ต์‹ฌ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ , ์Šคํ”„๋ง ๊ธฐ๋ณธ๊ธฐ๋ฅผ ํ™•์‹คํžˆ ๋‹ค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค., - ๊ฐ•์˜ ์†Œ๊ฐœ | ์ธํ”„๋Ÿฐ...

www.inflearn.com