๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IT/Spring

[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ - ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ, ์‹ฑ๊ธ€ํ†ค ๋ฐฉ์‹์˜ ์ฃผ์˜์ )

by YeonBu 2023. 10. 30.
728x90

/* ์ด ๊ธ€์€ ๊น€์˜ํ•œ๋‹˜์˜ ๊ฐ•์˜๋ฅผ ๋ณด๊ณ  ์ •๋ฆฌํ•˜๋ ค๊ณ  ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

   ๊ฐœ์ธ์ ์ธ ๊ณต๋ถ€๋ฅผ ์œ„ํ•ด ์˜ฌ๋ฆฌ๋Š” ๊ธ€์ด๋ฏ€๋กœ ์ค‘๊ฐ„ ์ค‘๊ฐ„ ์ฝ”๋“œ๋Š” ์ƒ๋žต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. */

 

 

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

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

www.inflearn.com

 

 

 

 

 

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

 

 

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

 

โœ” ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ๋•๋ถ„์— ๊ณ ๊ฐ์˜ ์š”์ฒญ์ด ์˜ฌ ๋•Œ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•ด์„œ ํšจ์œจ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.

โœ” ๊ธฐ๋ณธ ๋นˆ ๋“ฑ๋ก ๋ฐฉ์‹์€ ์‹ฑ๊ธ€ํ†ค์ด์ง€๋งŒ, ์‹ฑ๊ธ€ํ†ค ๋ฐฉ์‹๋งŒ ์ง€์›ํ•˜๋Š” ๊ฑด ์•„๋‹˜! ๋’ค์— ๊ฐ•์˜์—์„œ ์„ค๋ช…ํ•ด์ฃผ์‹ ๋‹ค๊ณ  ํ•จ.

 

 

 

SingletonTest

 

@Test
@DisplayName("์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ์‹ฑ๊ธ€ํ†ค")
void springContainer() {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    // ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š”์ง€ ํ™•์ธ
    MemberService memberService1 = ac.getBean("memberService", MemberService.class);
    MemberService memberService2 = ac.getBean("memberService", MemberService.class);

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

    Assertions.assertThat(memberService1).isSameAs(memberService2);

}

 

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

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

โœ” ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์ด๋Ÿฐ ๊ธฐ๋Šฅ ๋•๋ถ„์— ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์˜ ๋ชจ๋“  ๋‹จ์ ์„ ํ•ด๊ฒฐํ•˜๋ฉด์„œ ๊ฐ์ฒด๋ฅผ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

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

 

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

 

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

โœ” ๋ฌด์ƒํƒœ๋ž€?

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

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

- ๊ฐ€๊ธ‰์  ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•ด์•ผํ•จ.

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

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

 

 

 

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

 

 

StatefulService

 

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;
    }

}

 

 

StatefulServiceTest

 

class StatefulServiceTest {

    static class TestConfig {

        @Bean
        public StatefulService statefulService() {
            return new StatefulService();
        }

    }

    @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);

        Assertions.assertThat(statefulService1.getPrice()).isEqualTo(20000);

    }
    
}

 

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

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

โœ” ์˜ˆ์‹œ๋Š” ์ตœ๋Œ€ํ•œ ๋‹จ์ˆœํžˆ ์„ค๋ช…ํ•œ๊ฑด๋ฐ ์‹ค์ œ ์‹ค๋ฌด์—์„œ ์ด๋Ÿฐ ๊ฒฝ์šฐ๋ฅผ ์ข…์ข… ๋ณธ๋‹ค๊ณ  ํ•œ๋‹ค.

โœ” ๊ณต์œ ํ•„๋“œ๋Š” ์กฐ์‹ฌํ•ด์•ผ ํ•˜๋ฉฐ ํ•ญ์ƒ ์Šคํ”„๋ฆฐ ๋นˆ์€ ๋ฌด์ƒํƒœ๋กœ ์„ค๊ณ„ํ•ด์•ผ ํ•œ๋‹ค!

 

 

 

๋ฐ˜์‘ํ˜•

'IT > Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์ปดํฌ๋„ŒํŠธ ์Šค์บ” - ์ปดํฌ๋„ŒํŠธ ์Šค์บ”๊ณผ ์˜์กด๊ด€๊ณ„ ์ž๋™ ์ฃผ์ž…)  (0) 2023.11.02
[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ - @Configration๊ณผ ์‹ฑ๊ธ€ํ†ค)  (0) 2023.10.30
[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ - ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์‹ฑ๊ธ€ํ†ค, ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด)  (0) 2023.10.30
[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ์Šคํ”„๋ง ๋นˆ - ๋‹ค์–‘ํ•œ ์„ค์ • ํ˜•์‹ ์ง€์›, BeanDefinition)  (1) 2023.10.28
[์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ] ์ธํ”„๋Ÿฐ ๊ฐ•์˜ ์ •๋ฆฌ(์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ์Šคํ”„๋ง ๋นˆ - BeanFactory์™€ ApplicationContext)  (0) 2023.10.28