Spring 완전 정복 코스

2. [스프링 핵심 원리 - 기본편] 스프링 컨테이너와 스프링 빈

늦깎이_개발자 2022. 4. 4. 17:45
반응형

1. 스프링 컨테이너

1) 스프링 컨테이너 생성

 아래와 같이 스프링 컨테이너를 생성할 수 있다. ApplicationContext를 스프링 컨테이너라고 한다. 이는 인터페이스인데, 이는 다양한 구현 클래스가 있다는 것을 의미한다. 아래에는 어노테이션 기반인 AnnotationConfigApplicationContext 클래스를 사용하였으나 XML 기반의 컨테이너를 사용할 수도 있다.

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
@Configuration
public class AppConfig {

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }

    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }
}

 

2) 스프링 컨테이너 생성 과정

 1) 스프링 컨테이너 생성 

 스프링 컨테이너 내에는 빈(Bean) 저장소가 있다. 빈 저장소는 빈 이름을 Key로 가지고 빈 객체를 값으로 가지는 저장소이다.

 2) 스프링 빈 등록

 스프링 컨테이너는 AppConfig과 같은 구성 정보를 바탕으로 빈을 생성하여 빈 저장소를 구성한다.

 3) 스프링 빈 의존 관계 설정

 스프링 컨테이너는 구성 정보를 참고해서 의존 관계를 주입(DI)한다.

 

2. 스프링 빈 조회

 스프링 컨테이너에서 부모 타입으로 빈을 조회하면, 자식 타입도 함께 조회된다. 따라서 만약 모든 자바 객체의 부모인 Object 타입으로 조회를 한다면, 모든 스프링 빈이 조회될 것이다.

class ApplicationContextExtendsFindTest {
    ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);

    @Test
    void findAllBeanByObjectType() {
        final Map<String, Object> beansOfType = ac.getBeansOfType(Object.class);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value = " + beansOfType.get(key));
        }
    }

    @Configuration
    static class TestConfig {
    }
}

 

3. BeanFactory와 ApplicationContext

1) BeanFactory

 BeanFactory는 스프링 컨테이너의 최상위 인터페이스이다. 스프링 빈을 관리하고 조회하는 역할을 담당한다.

2) ApplicationContext

 BeanFactory의 기능을 모두 상속받아서 제공하는 인터페이스이다. ApplicationContext는 빈 관련 기능 이 외에도 다양한 부가 기능을 제공한다. 

 1) 메시지 소스를 활용한 국제화 기능(MessageSource)

 2) 환경 변수(EnvironmentCapable) : 로컬, 개발, 운영 등을 구분해서 처리

 3) 애플리케이션 이벤트(ApplicationEventPublisher) : 이벤트를 발행하고 구독하는 모델을 지원

 4) 편리한 리소스 조회(ResourceLoader) : 파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회

 

BeanFactory를 직접 사용할 일은 거의 없다. 부가 기능이 포함된 ApplicationContext를 사용한다.

 

4. 스프링 빈 설정 메타 정보 - BeanDefinition

 앞서 말했듯이 ApplicationContext는 인터페이스이고 이를 구현한 다양한 클래스가 있다. 예를 들어 어노테이션 기반으로 구성 정보를 제공하는 AnnotationConfigApplicationContext가 있고, xml로 구성 정보를 제공하는 GenericXmlApplicationContext가 있다. 이렇듯 스프링이 다양한 설정 형식을 지원하는 것을 가능하게 해주는데에는 BeanDefinition이라는 추상화가 있다. 스프링 컨테이너는 자바 코드인지 xml인지 몰라도 된다. 오직 BeanDefinition만 알면 된다. 스프링 컨테이너는 BeanDefinition 정보를 기반으로 빈을 생성한다. 이는 역할과 구현을 분리해야한다는 객체 지향적 설계 원칙을 따른 것이다.

1) BeanDefinition 정보

  • BeanClassName : 생성할 빈의 클래스 명(자바 설정처럼 팩토리 역할의 빈을 사용하면 없음)
  • factoryBeanName : 팩토리 역할의 빈을 사용할 경우 이름, 예) appConfig
  • factoryMethodName : 빈을 생성할 때 팩토리 메서드 이름, 예) memberService
  • Scope : 싱글톤이 기본값
  • lazyInit : 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 떄까지 최대한 생성을 지연 처리하는지의 여부
  • InitMethodName : 빈을 생성하고, 의존 관계를 적용한 뒤에 호출되는 초기화 메서드 명
  • DestroyMethodName : 빈의 생명 주기가 끝나고 제거되기 직전에 호출되는 메서드 명
  • Constructor arguments, Properties : 의존 관계 주입에서 사용된다. (자바 설정처럼 팩토리 역할의 빈을 사용하면 없음)

 

반응형