인프런 커뮤니티 질문&답변

hi_man159님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 기본편

@Configuration과 바이트코드 조작의 마법

@Configuration 유무 질문

작성

·

892

0

안녕하세요,

 

@Bean이 있더라도,

@Configuration이 있어야만,

싱글톤이 보장된다(프록시,,,)고 알고 있습니다...

 

그러나 강의 중에 보면

Class TestConfig에 @Configuration이 없어도

싱글톤 처럼 작동을 하네요,,

(statefulService1 = hello.core.singleton.StatefulService@d78795

statefulService2 = hello.core.singleton.StatefulService@d78795)

 

해당 부분은 왜 그런지 자세한 설명 요청드립니다...

 

public class StatefulServiceTest {
    @Test
    void statefulServiceSingleton() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
        StatefulService statefulService1 = ac.getBean("statefulService", StatefulService.class);
        StatefulService statefulService2 = ac.getBean("statefulService", StatefulService.class);
        System.out.println("statefulService1 = " + statefulService1);
        System.out.println("statefulService2 = " + statefulService2);
        //ThreadA: A사용자 10000원 주문
        statefulService1.order("userA", 10000);
        //ThreadB: B사용자 20000원 주문
        statefulService2.order("userB", 20000);
        //ThreadA: 사용자A 주문 금액 조회
        int price = statefulService1.getPrice();
        //ThreadA: 사용자A는 10000원을 기대했지만, 기대와 다르게 20000원 출력
        System.out.println("price = " + price);
        Assertions.assertThat(statefulService1.getPrice()).isEqualTo(20000);
    }
//    @Configuration
    static class TestConfig {
        @Bean
        public StatefulService statefulService() {
            return new StatefulService();
        }
    }
}


답변 1

0

안녕하세요. hi_man159님, 공식 서포터즈 OMG입니다.
.

올리신 코드와 같이 TestConfig에 @Bean으로 statefulService가 빈으로 등록되면 getBean으로 조회할 때 처음 등록한 빈을 조회해옵니다.

반면 아래와 같이 코드를 작성한다고 하면 강의에서처럼 싱글톤을 보장하지 않게 됩니다.

@Test
void statefulServiceSingleton() {
    ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
    StatefulService statefulService1 = ac.getBean(StatefulService.class);
    StatefulService statefulService2 = ac.getBean(StatefulService.class);
    System.out.println("statefulService1 = " + statefulService1);
    System.out.println("statefulService2 = " + statefulService2);
    //ThreadA: A사용자 10000원 주문
    int userAPrice = statefulService1.order("userA", 10000);
    int userBPrice = statefulService2.order("userB", 10000);
    //int price = statefulService1.getPrice();
    //System.out.println("price = " + price);
    Assertions.assertThat(userAPrice).isEqualTo(10000);
}

static class TestConfig {
    @Bean
    public StatefulService statefulService() {
        System.out.println("TestConfig.statefulService");
        return new StatefulService();
    }

    @Bean
    public StatefulRepository statefulRepository() {
        System.out.println("TestConfig.statefulRepository");
        return new StatefulRepository(statefulService());
    }

}

image
.
감사합니다.

안녕하세요 !

작성해주신 답변을 보고 궁금증이 생겨 질문드립니다.

답변해주신 내용의 코드처럼 작성하면 싱글톤 보장이 되지 않는다고 하셨는데,
같이 올려주신 출력 결과를 보면
statefulService1과 statefulService2가 서로 같은 객체인 걸로 나오는데
혹시 어떤 부분에서 싱글톤 보장이 되지 않는다고 하신 걸까요?