Spring Container(싱글톤 컨테이너)

YH·2023년 4월 13일
0

✅ Spring Container

  • Spring Container란, 스프링에서 자바 빈을 관리하는 공간이며 빈의 생성 및 소멸(빈의 생명주기)을 관리해주는 역할을 수행한다.
  • 객체들 간의 의존 관계를 스프링 컨테이너가 런타임 과정에서 자동으로 주입해준다.

✅ 스프링 컨테이너 종류

  • BeanFactory
  • ApplicationContext

BeanFactory

  • 빈의 등록, 생성, 조회, 반환 등의 빈을 관리하는 역할을 하고 getBean() 메소드를 통해 빈을 인스턴스화 하는 등의 기능을 한다.
  • 빈에 대한 정의는 즉시 수행하지만, 요청이 있기 전까지는 빈을 인스턴스화 하지 않는다.
  • getBean()이 호출되는 시점에 빈을 인스턴스 화 하고 빈의 생명주기가 시작된다.

ApplicationContext

  • BeanFactory를 상속, 확장하여 추가적인 기능을 덧붙혀 제공하는 인터페이스
  • 컨텍스트 초기화 시점에 모든 싱글톤 빈을 미리 생성하므로, 인스턴스를 즉시 사용하게 보장한다.
  • ApplicationContext는 아래와 같은 부가적인 기능을 제공한다.
    • ApplicationContext가 제공하는 부가기능
    1. MessageSource
      : 메세지 소스를 활용한 국제화기능
      즉, 국가별로 그 나라에 맞는 언어로 나오도록 하는 기능
    2. EnvironmentCapable
      : 로컬, 개발, 운영등을 구분해서 처리할 수 있게 하는 기능
    3. ApplicationEventPublisher
      : 이벤트를 발행하고 구독하는 모델을 편리하게 지원하는 기능
    4. ResourceLoader
      :파일 클래스패스, 외부 등에서 리소스를 편리하게 조회하게 지원하는 기능

✅ 스프링 컨테이너 설정 방식 - 자바 코드, XML

  • 스프링 컨테이너는 자바뿐아니라 XML이나 Groovy등 다양한 방식으로 스프링 컨테이너를 생성할 수 있다.
  • xml 설정 방식은 최근에는 거의 사용되지 않는다.
package hello.core.xml;

import hello.core.member.MemberService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

import static org.assertj.core.api.Assertions.assertThat;

@DisplayName("XML을 이용한 스프링 컨테이너 생성을 시도한다.")
public class XmlAppContext {

    @Test
    @DisplayName("XML파일을 설정정보로 넘겨준 뒤 빈을 조회한다.")
    void xmlAppContext() {
        ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
        MemberService memberService = ac.getBean("memberService", MemberService.class);
        assertThat(memberService).isInstanceOf(MemberService.class);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="memberService" class="hello.core.member.MemberServiceImpl">
        <constructor-arg name="memberRepository" ref="memberRepository" />
    </bean>

    <bean id="memberRepository" class="hello.core.member.MemoryMemberRepository"/>

    <bean id="orderService" class="hello.core.order.OrderServiceImpl">
        <constructor-arg name="memberRepository" ref="memberRepository"/>
        <constructor-arg name="discountPolicy" ref="discountPolicy"/>
    </bean>

    <bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy"/>

</beans>

✅ 스프링 빈 설정 메타 정보 - BeanDefinition

  • 스프링 컨테이너를 생성할 때 위 처럼 다양한 방식을 지원할 수 있는 이유는 BeanDefinition 이라는 인터페이스가 사용되기 때문이다.
  • 자바 코드, xml 등으로 설정 정보를 전달하면 아래와 같은 방식으로 각각의 설정정보 클래스에 맞는 BeanDefinitionReader를 사용해 해당 설정정보를 읽어서 빈 메타정보인 BeanDefinition을 생성해 전달한다.
  • 형식의 설정 정보(ex: JSON, TXT등)를 추가하고 싶다면 해당 형식을 읽을 수 있는 XxxBeanDefinitionReader를 만들어서 BeanDefinition을 생성하면 된다.

✅ Singleton Container

  • 스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리한다.
  • 스프링 컨테이너는 싱글톤 컨테이너 역할을 한다. 싱글톤 객체를 생성하고 관리하는 기능을 싱글톤 레지스트리라고 한다.
  • 스프링 컨테이너는 기존의 싱글톤 패턴의 단점들을 해결하면서 객체를 싱글톤으로 유지할 수 있도록 해준다. (싱글톤 패턴 단점)

업로드중..

💡참고: 스프링의 기본 빈 등록 방식은 싱글톤이지만, 싱글톤 방식만 지원하는 것은 아니다. 요청할 때마다 새로운 객체를 생성해서 반환하는 기능도 제공한다. - Bean Scope(빈 스코프)

✅ 싱글톤 방식의 주의점

  • 싱글톤 패턴이든, 싱글톤 컨테이너든, 객체 인스턴스를 하나만 생성해서 공유하므로 싱글톤 객체는 상태를 유지(stateful)하게 설계하면 안된다.
  • 무상태(stateless)로 설계해야 하는데, 무상태라는 것은
    • 특정 클라이언트에 의존적인 필드가 있으면 안된다.
    • 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안된다.
    • 가급적 읽기만 가능해야 한다.
    • 필드 대신에 자바에서 공유되지 않는 지역변수, 파라미터, ThreadLocal등을 사용해야 한다.

참고 Reference

profile
하루하루 꾸준히 포기하지 말고

0개의 댓글