[Spring] What - Application Context와 Singleton

하쮸·2025년 1월 4일

Error, Why, What, How

목록 보기
11/70
  • 애플리케이션 컨텍스트와 스프링에서 빈의 처리 과정, 그리고 싱글톤에 대해 학습.

1. 애플리케이션 컨텍스트(Application Context)

  • 스프링(Spring)에는 빈(Bean)생성관계설정과 같은 제어를 담당하는 IoC(Inversion of Control) 컨테이너빈 팩토리(Bean Factory)존재함.
    • 하지만 기능이 제한적이라 스프링에서는 빈 팩토리상속받아서 확장된 형태인 애플리케이션 컨텍스트(Application Context)를 주로 사용함.
  • 애플리케이션 컨텍스트는 설정 정보를 참고하여 IoC를 적용하고, 빈의 생성과 관계 설정을 총괄함.
    • 스프링 애플리케이션 전반에 걸쳐 모든 구성요소의 제어 작업을 담당하는 IoC 엔진임.
    • IoC 방식을 따라 만들어진 일종의 빈 팩토리임.
      • 빈 팩토리라고 말할 때는 빈을 생성하고 관계를 설정하는 IoC의 기본 기능에 초점을 맞춘 것.
    • 객체를 직접 생성하거나 관계를 설정하는 코드가 없고 대신 생성 정보와 연관관계 정보를 읽어서 처리함.
    • 싱글톤을 저장하고 관리하는 싱글톤 레지스트리이기도 함.
    • 스프링은 기본적으로 별다른 설정을 하지 않으면 내부에서 생성하는 빈 오브젝트를 모두 싱글톤으로 만듦.
    • Ex) @Configuration과 같은 에노테이션이 대표적인 IoC의 설정 정보임.

1-1. 빈, 빈 팩토리.

  • 빈 팩토리(Bean Factory).
    • 스프링 프레임워크의 IoC(Inversion of Control) 컨테이너 중 하나로 빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트.
  • 빈(Bean).
    • 스프링에서는 스프링이 제어권을 가지고 직접 생성하고, 의존관계를 부여하는 오브젝트를 Bean이라함.
    • 스프링에서 빈 등록은 XML, 자바 코드(애너테이션)를 통해 할 수 있음.

1-2. 빈(Bean) 요청 시 처리 과정

  • 클라이언트에서 특정 빈을 요청하면 애플리케이션 컨텍스트는 아래와 같은 과정을 거쳐 빈을 반환함.

    • Application Context는 @Configuration이 붙은 클래스들을 설정 클래스로 등록해놓고, @Bean이 붙은 메소드명으로 빈 목록을 생성함.

    • 클라이언트가 해당 빈을 요청.

    • Application Context는 빈 목록에서 요청한 빈이 있는지 찾고 설정 클래스로부터 빈 생성을 요청한 뒤 생성된 빈을 반환함.

      • 빈 생성 메소드(@Bean)을 호출해서 객체를 생성해서 반환.
  • 구체적으로는 Spring 내부에서 Reflection API를 이용해 빈 정의에 나오는 클래스 이름을 이용하거나 빈 팩토리를 통해 빈을 생성함.
    • Reflection API 사용.
      • 리플렉션 API 참고.
      • 스프링은 빈을 생성할 때, 빈 정의(클래스 이름 or 객체 생성 정보)를 통해 해당 클래스를 동적으로 불러옴.
      • 이때 Reflection API를 사용해서, 런타임 시점에 클래스 이름을 보고 해당 클래스를 메모리에 로드하고 그 클래스를 객체로 생성함.
      • Ex) @Bean 어노테이션이 붙은 메소드가 반환하는 객체가 있다면, Spring은 Reflection을 d이용해서 그 클래스를 불러오고, 그 클래스를 기반으로 객체를 생성함.
        이 과정은 컴파일 시점이 아니라 런타임, 즉 실행 시점에 이루어짐.
    • 빈 팩토리를 통한 빈 생성.
      • 스프링의 빈 팩토리는 Spring IoC 컨테이너에서 빈 정의(클래스 이름 or 객체 생성 정보)를 통해 빈을 생성하고 관리하는 핵심적인 역할.
      • 스프링은 빈 팩토리를 통해 미리 정의된 빈(@Bean통해 메소드에서 반환하는 객체, @Component, @Service 등)을 생성하거나, 요청에 따라 동적으로 빈을 생성하여 관리함.

1-3. Application Context의 장점.

  • 클라이언트는 @Configuration이 붙은 구체적인 팩토리 클래스를 알 필요가 없음.
    • 애플리케이션이 발전할 수록 팩토리 클래스 또한 증가함.
      • 클라이언트는 원하는 객체를 가져오려면 어떤 팩토리 클래스에 접근해야 하는지 알아야 하는 번거로움이 생김.
    • 애플리케이션 컨텍스트를 사용하면 팩토리 클래스가 증가해도 이에 직접 접근할 필요가 없어짐.
      즉, 일관된 방식으로 원하는 빈을 가져올 수 있움.
  • 애플리케이션 컨텍스트는 종합 IoC 서비스를 제공.
    • 애플리케이션 컨텍스트는 객체의 생성과 관계 설정이 끝이 아님.
    • 객체가 만들어지는 방식과 시점 및 전략 등을 상황에 맞게 유연하게 설정할 수 있고, 그 외에도 후처리나 인터셉트 등과 같은 다양한 기능이 존재.
  • 애플리케이션 컨텍스트를 통해 다양한 빈 검색 방법을 제공.
    • 애플리케이션 컨텍스트에서 빈 목록을 관리하므로 빈의 이름이나 타입 또는 에노테이션 설정 등으로 빈을 찾을 수 있음.
      • 이렇게 빈을 직접 찾는 방식은 의존성 검색(dependency lookup)이라 함.

2. Spring의 Singleton


2-1. Spring에서 싱글톤을 사용하는 이유.

  • 애플리케이션 컨텍스트에 의해 등록된 빈은 일반적으로 싱글톤으로 관리됨.
    • 즉, 스프링에 여러 번 빈을 요청하더라도 매번 동일한 객체를 반환해 준다는 것.
  • 애플리케이션 컨텍스트가 싱글톤으로 빈을 관리하는 이유는 대규모 트래픽을 처리할 수 있도록 하기 위함.
    • 스프링의 경우 최초에 설계될 때 부터 대규모의 엔터프라이즈 환경에서 요청을 처리할 수 있도록 설계 및 고안되었음.
    • 이에 맞춰 계층적인 처리 구조(Controller, Service, Repository 등)로 나뉘어지게 되었음.
  • 매번 클라이언트에서 요청이 올 때마다 각 로직을 처리하는 빈을 새로 만들어서 사용한다고 가정.
    • 요청 1번에 5개의 객체가 만들어질 경우.

      1초에 500번 요청.

      초당 2500개의 새로운 객체가 생성됨.
      서버가 감당하기 힘듦. 그래서 필요한 것이 싱글톤.
    • 위와같은 문제를 해결하고자 빈을 싱글톤 스코프로 관리해서 1개의 요청이 왔을 때 여러 쓰레드가 빈을 공유해 처리하도록 하였음.

2-2. Spring에서 관리하는 싱글톤의 장점.

  • Java로 기본적인 싱글톤 패턴을 구현할 땐 아래와 같은 단점들이 발생함.

    • private 생성자를 갖고 있어서 상속이 불가능함.
    • 테스트하기 힘듦.
    • 서버 환경에서는 싱글톤이 1개만 생성됨을 보장하지 못함.
    • 전역 상태를 만들 수 있기 때문에 객체지향적이지 못함.
  • 그래서 스프링은 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 제공.

    • 이게 바로 싱글톤 레지스트리(Singleton Registry).
    • 스프링 컨테이너는 싱글톤을 생성하고, 관리 및 공급하는 컨테이너이기도 함.

2-2-1. 싱글톤 레지스트리의 장점.

  • static 메소드나 private 생성자 등을 사용하지 않아서 객체지향적으로 개발을 할 수 있음.

  • 테스트 하기가 편리함.

  • 기본적으로 싱글톤이 멀티쓰레드 환경에서 서비스 형태의 객체로 사용되기 위해서는 내부에 상태정보를 갖지 않는 무상태(Stateless) 방식으로 만들어져야함.

    • 왜냐하면 만약 여러 쓰레드들이 동시에 상태를 접근하여 수정한다면 상당히 위험하기 때문이다.
  • 기본적으로 싱글톤은 멀티쓰레드 환경에서 서비스 형태의 객체로 사용되기 위해서는 내부에 상태 정보를 갖지 않는 무상태(Stateless) 방식으로 만들어져야함.

    • 객체 내부에 상태 정보를 가지고있지 않고 만드는 방식.
    • 왜냐하면 여러 쓰레드가 동시에 상태 정보를 수정할 경우, 데이터 손상이나 예상치 못한 에러 및 결과가 발생할 수 있기 때문.

3. IoC, DI.


3-1. IoC.

  • Ioc(Inversion of control, 제어의 역전)
    • 프로그램의 제어 흐름 구조가 뒤바뀌는 것.
  • 일반적인 프로그램 흐름
    • 일반적인 프로그램의 흐름은 main() 메소드와 같이 프로그램이 시작되는 지점에서 사용할 오브젝트를 결정 -> 결정한 오브젝트를 생성 -> 만들어진 오브젝트에 있는 메서드를 호출 -> 그 오브젝트 메서드 안에서 다음에 사용할 것을 결정하고 호출하는 식의 작업이 반복됨.
  • IoC의 프로그램 흐름

    • IoC에서는 오브젝트가 자신이 사용할 오브젝트를 스스로 선택하거나, 생성하지 않음.
    • 모든 제어 권한을 자신이 아닌 다른 대상에게 위임하기 때문.
    • 스프링에서는 애플리케이션 컨텍스트(application context)라고하는 IoC 컨테이너를 통해 IoC를 관리함.
      • 컨테이너는 특정 객체의 생성과 관리를 담당하고, 객체 운용에 필요한 다양한 기능을 제공.
  • 스프링은 Ioc를 모든 기능의 기초가 되는 기반기술로 삼고 있으며, Ioc를 극한까지 적용하고 있는 프레임워크.

    • 스프링의 대표적인 IoC 동작원리로 DI(Dependency Injection)이 있음.

  • 프레임워크는 제어의 역전 개념이 적용된 대표적인 기술이고 단지 미리 만들어둔 반제품이나 확장해서 사용할 수있도록 준비된 추상 라이브러리의 집합이 아님.
  • 라이브러리를 사용하는 애플리케이션 코드는 애플리케이션 흐름을 직접 제어함.
  • 반면에 프레임워크는 반대로 애플리케이션 코드가 프레임워크에 의해 사용됨.
    • 일반적으로 프레임워크 위에 개발된 클래스를 등록해두고, 프레임워크가 흐름을 주도하는 중에 개발자가 만들 애플리케이션 코드를 사용하도록 만드는 방식.


3-2. DI.

  • DI(Dependency Injection, 의존성 주입.)
    • DI는 의존관계 주입, 의존관계 설정이라는 의미.
      • 의존관계.
        • 한쪽의 변화가 다른 쪽에 영향을 주는 것.
        • Java에서는 인터페이스를 통해 의존관계를 제한하여 변경에서 자유로워질 수 있음.
    • 스프링 IoC 기능의 대표적인 동작원리임.
    • DI는 오브젝트 레퍼런스를 외부로부터 제공(주입)받고 이를 통해 그 밖에 다른 오브젝트와 의존관계가 만들어지는 것임.


4. 참고.

profile
Every cloud has a silver lining.

0개의 댓글