원문 : Chapter 3. Bean Visibility

JavaConfig의 멋진 기능 중 하나는 bean의 가시성을 설정할 수 있다는 것이다. JavaConfig는 메소드 접근 지시자를 사용하여 메소드에서 반환할 bean에 접근 할 수 있는지 없는지 여부를 결정할 수 있다.

다음의 설정을 살펴보자.

@Configuration
public abstract class VisibilityConfiguration {

  @Bean
  public Bean publicBean() {
     Bean bean = new Bean();
     bean.setDependency(hiddenBean());
     return bean;
  }
 
  @Bean
  protected HiddenBean hiddenBean() {
     return new Bean("protected bean");
  }

  @Bean
  private HiddenBean secretBean() {
     Bean bean = new Bean("private bean");
     // hidden beans can access beans defined in the 'owning' context
     bean.setDependency(outsideBean());
  }

  @ExternalBean
  public abstract Bean outsideBean()
}

위 설정 내용을 바탕으로 다음과 같은 XML 설정 파일을 사용할 수 있다.(여러 설정 파일 종류를 혼용하는 전략에 대해서는 본 챕터에서 다룰 것이다.)

<beans>
 <!-- the configuration above -->
 <bean class="my.java.config.VisibilityConfiguration"/>

 <!-- Java Configuration post processor -->
 <bean class="org.springframework.config.java.process.ConfigurationPostProcessor"/>

 <bean id="mainBean" class="my.company.Bean">
    <!-- this will work -->
    <property name="dependency" ref="publicBean"/>
    <!-- this will *not* work -->
    <property name="anotherDependency" ref="hiddenBean"/>
 </bean>
</beans>

위의 설정에서 하나의 JavaConfig가 설정에 포함되며, 3개의 빈을 생성할 책임을 지고 있다. publicBean, hiddenBean 그리고 secretBean이다. 이 세개의 bean들은 각자 서로를 참조할 수는 있지만, ApplicationContext 입장에서는 오직 publicBean만 참조할 수 있다. hiddenBean과 secretBean은 접근이 오직 VisiblilityConfiguration 내부로 제한되어 있다.

@Bean 애노테이션이 달리 메소드 중에 public이 아닌 것(protected, private, defalut)들은 모두 '감춰진' bean으로 생성될 것이다.

위의 예제에서, mainBean은 publicBean과 heddenBean을 사용하여 설정하고 있다. 하지만, hiddenBean은 숨겨져 있기 때문에 런타임시에 다음과 같은 에러를 발생시킨다.

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'hiddenBean' is defined
 ...

가시성을 제공하기 위해, JavaConfig는 Spring 컨테이너가 제공하는 application context 상속구조의 장점을 받아들였다. 자식 애플리케이션 컨테이너에서 숨겨진 빈들을 소유하고있는  부모 컨텍스트에 있는 빈들에 접근할 수 있다.