[Spring] Singleton

Goghยท2023๋…„ 1์›” 2์ผ
0

Spring

๋ชฉ๋ก ๋ณด๊ธฐ
7/23

๐ŸŽฏ ๋ชฉํ‘œ : Singleton ํŒจํ„ด๊ณผ ์Šคํ”„๋ง Singleton ์ปจํ„ฐ์—๋„ˆ์— ๋Œ€ํ•œ ์ด

๐Ÿ“’ Singleton Pattern

๐Ÿ“Œ Why

  • ์Šคํ”„๋ง์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  Java๋กœ๋งŒ ๊ตฌํ˜„ํ•œ Config DI ์ปจํ…Œ์ด๋„ˆ๋Š” ์š”์ฒญํ• ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  • 100๋ฒˆ ์š”์ฒญ๋˜๋ฉด 100๊ฐœ์˜ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์†Œ๋ฉธ๋˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•  ๊ฒƒ์ด๋‹ค.
  • ์ด๋Ÿฐ ๋ฌธ์ œ์ ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด๋Š” 1๊ฐœ๋งŒ ์ƒ์„ฑ๋˜๊ณ  1๊ฐœ์˜ ๊ฐ์ฒด๋กœ ๊ณต์œ ํ•˜๋Š” ํŒจํ„ด์ธ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

๐Ÿ“Œ Singleton

  • ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋”ฑ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.
public class SingletonService {
//1. static ์˜์—ญ์— ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•œ๋‹ค.
	private static final SingletonService instance = new SingletonService();

//2. public static์œผ๋กœ ์ด๋ฏธ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜๋ฐ›๋Š” ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ ๋‹ค.
    public static SingletonService getInstance() {
   		return instance;
    }

//3. ์ƒ์„ฑ์ž๋ฅผ private์œผ๋กœ ์„ ์–ธํ•ด์„œ ์™ธ๋ถ€์—์„œ new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์„ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š”๋‹ค.
    private SingletonService() {
    }

    public void logic() {
    	System.out.println("์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด ๋กœ์ง ํ˜ธ์ถœ");
    }
}
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ๋งŒ๋“ค์–ด ์‹คํ–‰ ํ•ด๋ณด๋ฉด ๋‘๋ฒˆ์˜ ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœํ–ˆ์Œ์—๋„ ๊ฐ™์€ ๊ฐ์ฒด์ธ ๊ฒƒ์„ ํ™•์ธํ• ์ˆ˜ ์žˆ๋‹ค.
    @Test
    @DisplayName("์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์ ์šฉํ•œ ๊ฐ์ฒด ์‚ฌ์šฉ")
    public void singletonServiceTest() {
	//private์œผ๋กœ ์ƒ์„ฑ์ž๋ฅผ ๋ง‰์•„๋‘์–ด. ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
	//new SingletonService();
        //ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜
        SingletonService singletonService1 = SingletonService.getInstance();
        //ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜
        SingletonService singletonService2 = SingletonService.getInstance();

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

        // singletonService1 == singletonService2
        assertThat(singletonService1).isSameAs(singletonService2);
    }

// ์ถœ๋ ฅ๊ฐ’
singletonService1 = hello.core.singleton.SingletonService@192c3f1e
singletonService2 = hello.core.singleton.SingletonService@192c3f1e

๐Ÿ“Œ Singleton์˜ ํ•œ๊ณ„

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

๐Ÿ“’ Singleton Container

๐Ÿ“Œ Singleton์˜ ํ•œ๊ณ„ ๊ทน๋ณต

  • ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ๋Š” ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.
  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ์„ ํ•˜๋ฉฐ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‹ฑ๊ธ€ํ†ค ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ผ ํ•œ๋‹ค.
  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ๋ชจ๋“  ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์˜ ๋‹จ์ ์„ ํ•ด๊ฒฐํ•˜๋ฉด์„œ ๊ฐ์ฒด์˜ ์‹ฑ๊ธ€ํ†ค์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋ณต์žกํ•œ ๊ตฌํ˜„ ์ฝ”๋“œ๊ฐ€ ํ•„์š”์—†๋‹ค.
  • DIP, OCP, ํ…Œ์ŠคํŠธ, ์ƒ์†์œผ๋กœ ๋ถ€ํ„ฐ ์ž์œ ๋กญ๋‹ค.
    @Test
    @DisplayName("์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ์‹ฑ๊ธ€ํ†ค")
    void springContainer() {
        AnnotationConfigApplicationContext ac
                = new AnnotationConfigApplicationContext(AppConfig.class);

        // ์กฐํšŒ 1
        // ์กฐํšŒ 2
        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);
    }

    //์ถœ๋ ฅ๊ฐ’
    memberService1 = hello.core.member.MemberServiceImpl@52d239ba
    memberService2 = hello.core.member.MemberServiceImpl@52d239ba
  • ์œ„ ์ฝ”๋“œ์—์„œ ๋”ฐ๋กœ ์‹ฑ๊ธ€ํ†ค์„ ๊ตฌํ˜„ํ•œ ๊ฒƒ์€ ์—†๋‹ค. AppConfig.class๋Š” ์˜์กด๊ด€๊ณ„ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด Bean๋“ค์„ ๋“ฑ๋ก ํ•ด๋‘์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

๐Ÿ“Œ Singleton์˜ ์„ค๊ณ„

  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ์˜ ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋“ , ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด๋“  ์ธ์Šคํ„ด์Šค ํ•˜๋‚˜๋กœ ๊ณต์œ ํ•˜๋Š” ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋Š” ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜๋ฉด ์•ˆ๋œ๋‹ค. ๋ฌด์ƒํƒœ ์„ค๊ณ„๋ฅผ ํ•ด์•ผํ•œ๋‹ค \= stateless
  • ํด๋ผ์ด์–ธํŠธ์— ์˜์กด์ ์ธ ํ•„๋“œ๊ฐ€ ์žˆ์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ• ์ˆ˜ ์žˆ๋Š” ํ•„๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์•ˆ๋œ๋‹ค.
  • \= ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค.
// StatefulService.java
public class StatefulService {
    private int price;

    public int order(String name, int price) {
        System.out.println("name = " + name+ " price = "+ price);
        this.price = price;

    }
    public int getPrice() {
        return price;
    }
}

// StatefulServiceTest.java
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);
        // ThreadA B ์‚ฌ์šฉ์ž 20000์ฃผ๋ฌธ
        statefulService2.order("userB",20000);

        //A์˜ ์ฃผ๋ฌธ ๊ธˆ์•ก ์กฐํšŒ
        int price = statefulService1.getPrice();
        System.out.println("price = " + price); // 20000

        // ๊ฐ™์€ ๊ฐ์ฒด๊ธฐ ๋•Œ๋ฌธ์— 10000์›์œผ๋กœ ํ• ๋‹น๋˜์—ˆ๋˜ price์˜ ๊ฐ’์ด 20000์œผ๋กœ ๋ฐ”๋€œ
        Assertions.assertThat(statefulService1.getPrice()).isEqualTo(20000);

    }

    static class TestConfig {
        @Bean
        public StatefulService statefulService() {
            return new StatefulService();
        }
    }
}
  • ์œ„ ์ฝ”๋“œ์—์„œ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ์‹ฑ๊ธ€ํ†ค์„ ์œ ์ง€ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ™•์ธ ํ• ์ˆ˜ ์žˆ๋‹ค.
  • userA๊ฐ€ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ์ œ๊ณตํ•˜๋Š” StatefulService ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ›์•„ 10000์›์˜ ์ฃผ๋ฌธ์„ ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.
  • ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— StatefulService ์˜ order ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉฐ ํ•„๋“œ์˜ price ๊ฐ’์€ 10000์›์ด ๋ ๊ฒƒ์ด๋‹ค,
  • userB๊ฐ€ ๋™์‹œ์— ย StatefulService ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ›์•„ 20000์›์˜ ์ฃผ๋ฌธ์„ ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ๊ฐ™์ด order ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•„๋“œ์˜ price ๊ฐ’์€ 20000์›์ด ๋ ๊ฒƒ์ด๋‹ค.
  • userA์™€ userB๊ฐ€ ๊ณต์œ ํ•œ StatefulService ์ธ์Šคํ„ด์Šค๋Š” ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋‹ค. ์ฝ”๋“œ์˜ ํ๋ฆ„์œผ๋กœ ๋ดค์„๋•Œ StatefulService ์ธ์Šคํ„ด์Šค์˜ ํ•„๋“œ๋ฉค๋ฒ„ price ๊ฐ’์€ ์ตœ์ข…์ ์œผ๋กœ 20000์ด ๋˜์–ด ์žˆ์„๊ฒƒ์ด๋‹ค.ย 
 Assertions.assertThat(statefulService1.getPrice()).isEqualTo(20000);
  • userA์˜ getPrice ๊ฐ’์„ ๋น„๊ต ํ–ˆ๋Š”๋ฐ 20000์ด ๋‚˜์™”๋‹ค. ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์„ค๊ณ„ํ•˜๊ฒŒ ๋˜๋ฉด ์ด๋Ÿฌํ•œ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ ํ• ์ˆ˜๋„ ์žˆ๋‹ค.
  • StatefulService ํด๋ž˜์Šค๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐœ์„  ํ•˜๊ฒŒ ๋˜๋ฉด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ ํ•˜๊ฒŒ๋œ๋‹ค.
public class StatefulService {

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

๐Ÿ“’ Singleton ๊ณผ @Configuration

๐Ÿ“Œ @Configuration

  • ์˜์กด ๊ด€๊ณ„๋ฅผ ์„ค์ •ํ•ด์ฃผ๋˜ AppConfig ์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๊ถ๊ธˆํ•œ์ ์ด ์ƒ๊ธด๋‹ค.
  • memberRepository()๊ฐ€ 2๋ฒˆ ํ˜ธ์ถœ ๋จ์œผ๋กœ์„œ new MemoryMemberRepository()๋„ 2๋ฒˆ ํ˜ธ์ถœ ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ๊ฐ€?
  • ๊ทธ๋ ‡๋‹ค๋ฉด 2๊ฐœ์˜ MemoryMemberRepository ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ๊ฐ€?
@Configuration
public class AppConfig {
    @Bean
    public MemberService memberService() {
        System.out.println("Call AppConfig.memberService");
        return new MemberServiceImpl(memberRepository());
    }
    @Bean
    public MemberRepository memberRepository() {
        System.out.println("Call AppConfig.memberRepository");
        return new MemoryMemberRepository();
    }
    @Bean
    public OrderService orderService() {
        System.out.println("Call AppConfig.orderService");
        return new OrderServiceImpl(
                memberRepository(),
                discountPolicy()
        );
    }
    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }
}
  • ๊ฐ Bean์— ๋ฉ”์†Œ๋“œ๋ช… ์ถœ๋ ฅ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๊ณ  ์•„๋ž˜ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๋ฉด ํ™•์ธ ํ• ์ˆ˜ ์žˆ๋‹ค.
    @Test
    void configurationTest() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

        MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
        OrderServiceImpl orderService = ac.getBean("orderService", OrderServiceImpl.class);
        MemberRepository memberRepository = ac.getBean("memberRepository", MemberRepository.class);

        MemberRepository memberRepository1 = memberService.getMemberRepository();
        MemberRepository memberRepository2 = orderService.getMemberRepository();
        System.out.println("memberRepository1 = " + memberRepository1);
        System.out.println("memberRepository2 = " + memberRepository2);
        System.out.println("memberRepository = " + memberRepository);

        AppConfig appConfig = ac.getBean(AppConfig.class);
        System.out.println("appConfig = " +appConfig.getClass());

        Assertions.assertThat(memberRepository1).isSameAs(memberRepository);
        Assertions.assertThat(memberRepository2).isSameAs(memberRepository);

    }
    // ์ถœ๋ ฅ๊ฐ’
Call AppConfig.memberService
Call AppConfig.memberRepository
Call AppConfig.orderService
memberRepository1 = hello.core.member.MemoryMemberRepository@68044f4
memberRepository2 = hello.core.member.MemoryMemberRepository@68044f4
memberRepository = hello.core.member.MemoryMemberRepository@68044f4
appConfig = class hello.core.AppConfig$$EnhancerBySpringCGLIB$$30511a3f
  • ๋ชจ๋“  MemoryMemberRepository ๊ฐ์ฒด๋Š” ๊ฐ™์€ ๊ฐ์ฒด๋กœ ํ™•์ธ ๋œ๋‹ค.
  • ๋ชจ๋“  Bean์€ ํ•œ๋ฒˆ์”ฉ๋งŒ ํ˜ธ์ถœ ๋˜๋Š” ๊ฒƒ์„ ๋ณผ์ˆ˜ ์žˆ๋‹ค.
  • appConfig ์˜ ์ถœ๋ ฅ ๊ฐ’์„ ๋ณด๋ฉด,
  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์ˆœ์ˆ˜ํ•œ AppConfig ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ CGLIB์ด ๋ถ™์€ AppConfig๋ฅผ ์ƒ์†๋ฐ›์€ ์ž„์˜์˜ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ์ด ์ž„์˜์˜ ํด๋ž˜์Šค๋ฅผ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด ๋†“์€ ๊ฒƒ์ด๋‹ค.
  • CGLIB๋ผ๋Š” ๋ฐ”์ดํŠธ ์กฐ์ž‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋“ฑ๋ก๋œ ์Šคํ”„๋ง ๋นˆ์˜ ์ž„์˜์˜ ์ธ์Šคํ„ด์Šค๋Š” ์–ด๋–ค ๊ธฐ๋Šฅ์„ ํ• ๊นŒ?
  • AppConfig@CGLIB๋Š” ๋“ฑ๋ก๋œ Bean๋“ค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‹ฑ๊ธ€ํ†ค์ด ๋ณด์žฅ๋˜๋„๋ก ํ•ด์ค€๋‹ค.
  • ์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์ด new MemoryMemberRepository()๊ฐ€ ์ค‘๋ณต ํ˜ธ์ถœ ๋˜๋”๋ผ๋„ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋™์ผํ•œ Bean์ด ์žˆ๋‹ค๋ฉด ํ•ด๋‹น Bean์„ ๋ฐ˜ํ™˜ ํ•ด์ฃผ๊ณ , ์—†๋‹ค๋ฉด Bean์œผ๋กœ ๋“ฑ๋กํ•ด์ฃผ๋Š”, ๋™์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.
profile
์ปดํ“จํ„ฐ๊ฐ€ ํ• ์ผ์€ ์ปดํ“จํ„ฐ๊ฐ€

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