본문 바로가기
Spring/인프런 토비의 Spring Boot

섹션 6-8 [자동 구성 기반 애플리케이션] @Configuration과 proxybeanMethods

by include_hoany 2024. 6. 14.

@Configuration과 proxybeanMethods

 

일반적으로 팩토리 메소드를 통해 객체를 생성한다면 팩토리 메소드를 실행할때마다 새로운 객체가 생성되게 됩니다.

static class MyConfig {  
      
    Common common() {  
        return new Common();  
    }  
  
      
    Bean1 bean1() {  
        return new Bean1(common());  
    }  
  
      
    Bean2 bean2() {  
        return new Bean2(common());  
    }  
  
}

 

일반적으로 위 처럼 MyConfig클래스를 만들고 bean1, bean2를 생성하는 팩토리 메소드를 가질때

 

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

Assertions.assertThat(bean1.common).isSameAs(bean2.common);

bean1, bean2모두 공통으로 가지고 있는 common객체는 서로 다른 객체이므로 테스트 결과는 실패하게 됩니다.

 

@Configuration  
static class MyConfig {  
    @Bean  
    Common common() {  
        return new Common();  
    }  
  
    @Bean  
    Bean1 bean1() {  
        return new Bean1(common());  
    }  
  
    @Bean  
    Bean2 bean2() {  
        return new Bean2(common());  
    }  
  
}

다만 위 처럼 Spring Container에서 관리될 수 있도록 구성정보를 등록하고 

 

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();  
ac.register(MyConfig.class);  
ac.refresh();  
  
Bean1 containerBean1 = ac.getBean(Bean1.class);  
Bean2 containerBena2 = ac.getBean(Bean2.class);  
Assertions.assertThat(containerBean1.common).isSameAs(containerBena2.common);

스프링 컨테이너에서 관리되도록 구성정보 class를 등록하고 구성정보를 통해 Bean을 호출하여 bean1, bean2객체가 공통으로 가지고 있는 common객체를 서로 같은지 비교해본다면 서로 같은 객체로 테스트는 성공하게 됩니다.

이런 결과가 발생한 이유는 @Configuration애노테이션의 독특한 특징 때문입니다. 해당 애노테이션을 사용하면 proxy패턴이 적용되게 되는데 Bean어노테이션으로 등록된 팩토리 메소드로 생성되는 객체들을 싱글턴으로 유지될 수 있게 해줍니다. 따라서 프록시 패턴으로 이미 생성된 객체들을 멤버변수로 가지고 있게 되고 해당 객체가 이미 만들어져 있다면 이미 만들어져 있는 객체를 활용하여 bean1, bean2 객체를 생성하게 됩니다.

 

@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
@Configuration(proxyBeanMethods = false)  
public @interface MyAutoConfiguration { }

다만 해당 proxy패턴이 불필요할 수 있는데 지난 섹션에서 proxy패턴 생성이 되는 부분이 스프링에서는 디폴트값으로 되어있습니다. proxy패턴을 생성하는것 또한 리소스를 차지하는 부분일 수 있으므로 불필요 하다면 proxy패턴을 생성하지 않도록 @Congifuration 속성중 proxyBeanMethods의 값을 false로 설정하여 proxy패턴을 사용하지 않을 수 있습니다. 해당 방법으로 상황에 따라 최적화를 진행할 수 잇습니다.