학습 테스트

Configuration의 default 구성 특징 테스트를 위한 준비

public class ConfigurationTest {
    @Test
    @DisplayName("Configuration의 default 구성 특징 테스트")
    public void configuration() {

    }

    @Configuration
    static class MyConfig {
        @Bean
        Common common() {
            return new Common();
        }

        @Bean
        Bean1 bean1() {
            return new Bean1(common());
        }

        @Bean
        Bean2 bean2() {
            return new Bean2(common());
        }
    }

    static class Bean1 {
        private final Common common;

        Bean1(Common common) {
            this.common = common;
        }
    }

    static class Bean2 {
        private final Common common;

        Bean2(Common common) {
            this.common = common;
        }
    }

    static class Common {

    }

    // Bean1 <-- Common
    // Bean2 <-- Common
}

MyConfig 생성 후 테스트

@Test
@DisplayName("Configuration의 default 구성 특징 테스트")
public void configuration() {

    MyConfig myConfig = new MyConfig();
    Bean1 bean1 = myConfig.bean1();
    Bean2 bean2 = myConfig.bean2();

    Assertions.assertThat(bean1.common).isSameAs(bean2.common); // 실패. 주고값이 다르기 때문에
}

MyConfig를 Spring의 구성정보로 사용하는 경우 테스트

@Test
@DisplayName("Configuration의 default 구성 특징 테스트")
public void configuration() {

    // MyConfig를 Spring의 구성정보로 사용하면 동작방식이 달라짐
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
    ac.register(MyConfig.class);
    ac.refresh();

    Bean1 bean1 = ac.getBean(Bean1.class);
    Bean2 bean2 = ac.getBean(Bean2.class);

    Assertions.assertThat(bean1.common).isSameAs(bean2.common); // 성공.
}

bean1과 bean2 오브젝트가 가지고있는 common이 일치하는 이유

image.png

Proxy 테스트

직접 proxy를 만들어서 스프링 컨테이너 내부에서 일어나는 빈 등록과정 테스트 진행

@Test
@DisplayName("스프링 빈 동작방식 테스트")
public void proxyCommonMethod() {
    MyConfigProxy myConfigProxy = new MyConfigProxy();// 확장해서 대체하는 방식으로 동작

    Bean1 bean1 = myConfigProxy.bean1();
    Bean2 bean2 = myConfigProxy.bean2();

    Assertions.assertThat(bean1.common).isSameAs(bean2.common); // 성공
}

확장한 MyConfigProxy 오브젝트를 통해서 common 메서드가 생성하는 오브젝트의 개수를 하나로 제한하고 재사용 할 수 있도록 캐싱하는 방식으로 동작하게 만든 것