Spring Framework의 핵심인 Spring Container(IoC 컨테이너라고도 함)는 빈을 조회, 등록 등 관리하는 역할을 가지고 있다.

참고로 빈들은 BeanFactory에 저장되는데, Key-Value 구조의 자료구조인 Map형태로 저장 됨.

GenericApplicationContext 내부에서 DefaultListableBeanFactory를 멤버로 가짐
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory 
 implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    ```
	private final Map<String, BeanDefinition> beanDefinitionMap 
    = new ConcurrentHashMap<>(256);
    ```
}

그렇다면 스프링 컨테이너가 어떻게 빈을 등록하는지 / 유지하는지 정리해보자.

빈 등록

스프링 컨테이너에 빈을 등록하는 방법으로는 굉장히 많은데 (ApplicationContext의 구현체는 수많음) 대표적으로 xml로 등록하는 방법과 Java의 어노테이션을 통한 방법이 있다.

우리는 Java의 어노테이션을 이용한 빈 등록 방법을 알아보겠다.

어노테이션을 통한 빈 등록

어노테이션을 통한 빈 등록은 모두 ComponentScan에 의존하게 되고 클래스를 통한 등록 / 메서드를 통한 등록으로 나뉜다.

클래스를 통한 등록

클래스를 통한 빈 등록은 @Component - @Target(ElementType.TYPE) 어노테이션을 활용하게 된다. ComponentScan에서 보이는 Component말이다.

@Component
public class MyBean {
	```
}

이렇게 클래스를 통해 빈을 등록하게 될 경우

  • 빈 이름은 myBean처럼 클래스명을 lower camel case로 바꿔 등록해준다.
    물론 custom name 가능
  • 주로 내가 만든 클래스를 빈으로 등록할 때 사용 (내가)

메서드를 통한 등록

메서드를 통한 빈 등록은
@Bean - @Target(ElementType.METHOD,ElementType.ANNOTATION_TYPE) 을 활용하게 된다. 그러나 이 어노테이션은 ComponentScan의 대상이 되지 못한다. 따라서 @Component내에 생성 메서드를 두고 @Bean을 붙임으로써 간접적으로 빈 등록이 되게 한다.

주의할 점은

  • @Configuration 클래스 내에 @Bean 메서드를 선언해야 해당 빈이 싱글톤 유지를 받을 수 있다.

싱글톤 유지

스프링 컨테이너는 기본적으로 빈들을 싱글톤으로 유지해준다. 어떤 역할인지 눈으로 확인해보자.

With 스프링 컨테이너

@Configuration
public class AppConfig {

    @Bean
    public MemberInstanceService memberInstanceService() {
        MemberInstanceService instanceService = new MemberInstanceService();

        System.out.println(instanceService); -------
        return instanceService;
    }

    @Bean
    public MemberService memberService() {
        MemberInstanceService instanceService = memberInstanceService();
        System.out.println(instanceService); --------
        return new MemberService(instanceService);
    }
}

출력 값

hello.springtx.AppConfig$MemberInstanceService@1190200a
hello.springtx.AppConfig$MemberInstanceService@1190200a

Without 스프링 컨테이너

위 소스코드에서 @Configuration 제거

hello.springtx.AppConfig$MemberInstanceService@70e8f8e
hello.springtx.AppConfig$MemberInstanceService@2e4b8173

이렇게 생성 역할을 하는 메서드를 여러번 호출했을 때, 일반적으로는 또 다시 new 연산자에 의해 새 인스턴스가 생기지만

스프링 컨테이너는 해당 빈이 BeanFactory에 등록돼있다면 (빈 이름으로 구분), 같은 객체의 레퍼런스를 리턴해주는 방식으로 빈을 싱글톤으로 유지하게 된다.

profile
울릉도에 별장 짓고 싶다

0개의 댓글

Powered by GraphCDN, the GraphQL CDN