토비의 스프링 Vol2. 1장 정리

바퀴달린 개발자·2022년 5월 16일

스프링

목록 보기
4/4

1.1 IoC 컨테이너: 빈 팩토리와 애플리케이션 컨텍스트

  • 오브젝트의 생성과 관계 설정, 사용, 제거 등의 작업을 애플리케이션 코드 대신 독립된 컨테이너가 담당한다. 이를 IoC라고 부른다.
  • IoC를 담당하는 컨테이너를 빈팩토리 또는 애플리케이션 컨텍스트라고 부르기도 한다.

빈팩토리
오브젝트의 생성과 오브젝트 사이의 런타임 관계를 설정하는 DI 관점으로 볼 때는 컨테이너를 빈팩토리라고 한다.

애플리케이션 컨텍스트
빈 팩토리 + 엔터프라이즈 애플리케이션을 개발하는 데 필요한 여러 가지 컨테이너 기능을 추가한 것

이 둘은 각각 BeanFactory, ApplicationContext라는 두 개의 인터페이스로 정의되어 있다.

  • ApplicationContext는 BeanFactory 인터페이스를 상속한 서브 인터페이스다.

=> IoC 컨테이너라고 말하는 것은 이 ApplicationContext를 구현한 클래스 오브젝트

1.1.1 IoC 컨테이너를 이용해 애플리케이션 만들기

1. ApplicationContext 구현 클래스의 인터페이스 만들기

StatiAppicationContext ac = new StaticApplicationContext(); // ApplicationContext 인터페이스 구현한 클래스

2. POJO 클래스와 설정 메타정보 설정

POJO

  • 특정 기술과 스펙에서 독립적, 의존관계에 있는 다른 POJO와 느슨한 결합을 갖도록 만들어야함.

책에서는 아래의 클래스를 생성

class Hello {}

interface Printer {}

class StringPrinter implements Printer {}

class ConsolePrinter implements Printer {}

설정 메타 정보

  • POJO 클래스들 중에 애플리케이션에서 사용할 것을 선정하고 이를 IoC 컨테이너가 제어할 수 있도록 적절한 메타 정보를 만들어 제공하는 작업

  • 스프링 컨테이너가 관리하는 오브젝트는 bean이라고 부른다.

  • 설정 메타정보는 바로 이 빈을 어떻게 만들고 어떻게 동작하게 할 것인가에 관한 정보

  • BeanDefinition 인터페이스로 표현되는 순수한 추상정보다.

  • 즉, 애플리케이션 컨텍스트는 바로 이 BeanDefinition으로 만들어진 메타정보를 담은 오브젝트를 사용해 IoC와 DI 작업을 수행한다.

  • 따라서, 스프링의 메타 정보는 특정한 파일 포맷이나 형식에 제한되거나 종속되지 않는다.

IoC 컨테이너가 사용하는 빈 메타 정보

  • 빈 아이디: 빈 오브젝트를 구분할 수 있는 식별자
  • 클래스: 빈으로 만들 POJO 클래스 또는 서비스 클래스 정보
  • 스코프: 싱클톤, 프로토타입과 같은 빈의 생성방식과 존재 범위
  • 프로프티 값 또는 참조: DI에서 사용할 프로퍼티 이름과 값 또는 참조하는 빈의 이름
  • 생성자 파라미터 값 또는 참조: DI에 사용할 생성자 파라미터 이름과 값 또는 참조할 빈의 이름
  • 지연된 로딩 여부, 우선 빈여부, 자동와이어링 여부, 부모 빈 정ㅇ보, 빈팩토리 이름 등

실습

  1. 디폴트 메타정보를 사용해서 싱글톤 빈 등록
StaticApplicationContext ac = new StaticApplicationContext();
ac.registerSingleton("hello1", Hello.class); // hell1이라는 이름의 싱클톤 빈으로 컨테이너 등록

// Ioc 컨테이너가 등록한 빈을 생성했는지 확인
Hello hello1 = ac.getBean("hello1", Hello.class);
assertThat(hello1, is(notNullValue());
  1. BeanDefinition 타입의 설정 메타 정보를 사용해서 빈 등록
BeanDefinition helloDef = new RootBeanDefinition(Hello.class);
helloDef.getPropertyValues().addPropertyValue("name", "Spring"); // 빈의 name 프로퍼티의 들어갈 값을 지정
ac.registerBeanDefinition("hello2", helloDef);
  • Hello 와 StringPrinter 사이의 관계는 설정 메타정보를 참고해서 런타임 시에 IoC 컨테이너가 주입해준다.

1.1.2 IoC 컨테이너의 종류와 사용 방법

하지만 직접 구현할일은 없을 걳이다.. 보통 자동으로 만들어지는 방법을 사용하기 때문..

StaticApplicationContext

GenericApplicationContext

  • 가장 일반적
  • 외부의 리소스에 있는 빈 설정 메타정보를 리더를 통해 읽어들여서 메타정보로 전환
  • 테스트 클래스를 만들면 GenericApplicationContext가 생성되고 @ContextConfiguration에 지정한 XML 파일로 초기화돼서 테스트 내에서 사용할 수 있도록 준비된다.

GenericXmlApplicationContext

WebApplicationContext

  • 제일 많이 슨다.

  • 웹 환경에서 사용할 때 필요한 기능이 추가된 애플리케이션 텍스트

  • 어딘가 특정 빈 오브젝트의 메소드를 호출함으로써 애플리케이션을 동작시켜야 한다.

  • 스프링 애플리케이션을 만들고 IoC 컨테이너를 직접 셋업했다면 빈을 가져와 기동하는 코드가 있어야한다. (getBean())

  • 그 이후에는 필요없다. 알아서 연ㅇ결되어 있으므로

  • IoC컨테이너의 역할은 이렇게 초기에 빈 오브젝트를 생성하고 DI한 후 최초로 애플리케이션을 기동할 빈 하나를 제공해주는 것까지이다.

  • 웹 애플리케이션은 독립 자바프로그램은 자바 vm 에게 main() 메소드를 가진 클래스를 시작시켜 달라고 요청할 수 있다.

  • 웹 환경에서는 서블릿 컨테이너가 브라우저로부터 오는 HTTP 요청을 받아서 해당 요청에 매핑되어 있는 서블릿을 실행해주는 방식으로 동작한다. 서블릿이 일종의 main() 메소드와 같은 역할을 해줌

웹 애플리케이션에서 스프링 애플리케이션을 기동시키는 방법은?

  1. main() 메소드 역할을 하는 서블릿 만ㄷ르어둠 미리 애플리케이션컨텍스트 생성
  2. 요청이 서블릿으로 들어올때마다 getBean()으로 필요한 빈을 가져와 정해진 메소드를 실행해준다.
  • 서블릿 컨테이너는: 요청을 받아서 서블릿을 동작시켜준다.
  • 서블릿은 웹 애플리케이션이 시작될 때 미리 만들어둔 웹 채플리케이션 컨텍스트에게 빈 오브젝트로 구성된 애플리케이션의 기동 역할을 해줄 빈을 요청해서 받아준다.
  • 스프링은 그래서 DispatcherServlet이라는 서블릿 제공 (요청마다 적절한 빈을 찾아서 실행해주는 기능을 가짐.)
  • 스프링이 제공해준 서블릿을 web.xml에 등록하는 것만으로 웹 환경에서 스프링 컨테이너가 만들어지고 애플리케이션을 실행하는 데 필요한 대부분의 준비는 끝이다.

1.1.3 IoC 컨테이너 계층 구조

  • 모든 애플리케이션 컨텍스트는 부모 애플리케이션 컨텍스트를 가질 수 있다. 이를 이용해 트리구조의 컨텍스트 계층을 만들 수 있다.
  • 각자 독립적으로 자신이 관리하는 빈을 갖고 있지만 DI를 위해 빈을 찾을 때는 부모 애플리케이션 컨텍스트의 빈까지 모두 검색한다.
  • 자신이 가진것이 우선이 된다.
  • 여러 애플리케이션 컨텍스트가 공유하는 설정을 만들기 위해서도 계층 구조가 사용된다.

1.1.4 웹 애플리케이션의 IoC 컨테이너 구성

  • 웹 애플리케이션 안에 WebApplicationContext 타입의 IoC 컨테이너를 둔다.

  • 자바 서버에는 하나 이상의 웹 모듈을 배치해서 사용할 수 있다.

  • 스프링은 보통 웹 모듈(WAR) 형태로 애플리케이션을 배포한다.

  • 하나의 웹 애플리케이션은 여러 개의 서블릿을 가질 수 있다.

  • 웹 요청을 한 번에 받을 수 있는 대표 서블릿을 등록해두고, 공통적인 선행 작업을 수행하게 한 후에, 각 요청의 기능을 담당하는 핸들러라고 불리는 클래스를 호출하는 방식이 일반적이다.

    프론트 컨트롤러 패턴
    몇 개의 서블릿이 중앙집중식으로 모든 요청을 다 받아서 처리하는 방식
    서블릿 숫자는 3개 이하

  • 웹 애플리케이션 안에서 동작하는 IoC 컨테이너는

  1. 스프링 애플리케이션의 요청을 처리하는 서블릿 안에서 만들어짐
  2. 웹 애플리케이션 레벨이서 만들어짐
    그래서 스프링 웹 애플리케이션에는 두 개의 컨테이너, WebApplicationContext object가 만들어진다.

웹 애플리케이션의 컨텍스트 계층 구조

  • 루트 웹 애플리케이션 컨텍스트
    - 서블릿 레벨에 등록되는 컨테이너들의 부모 컨테이너
    • 최상단에 위치한 루터 큰텍스트
  • 프론트 컨트롤러 역할을 하는 서블릿은 독립적으로 애플리케이션 컨텍스트가 만들어진다. 이런 경우 각 서블릿이 공유하는 공통 빈들은 웹 애플리케이션 레벨의 컨텍스트에 등록한다.
  • 보통은 프론트 컨트롤러 역할의 애플리케이션 컨텍스는 한개만 사용한다. 근데 왜 계층구조를 만들까? -> 웹 기술에 의존적인 부분과 그렇지 않은 부분을 구분하기 위함.
    ex) jsp, 스트럿츠, ajax

루트 애플리케이션 컨텍스트 얻기

WebApplicationContextUtils.getWebApplicationContext(SeveletContext sc)
  • SevletContext는 웹 애플리케이션마다 하나씩만들어지는 것으로 서블릿 런타임 환경정보를 담고 있다.

웹 애플리케이션의 컨텍스트 구성 방법

  1. 컨텍스트 계층구조 만들기
  2. 컨텍스트를 하나만 사용함.

루트 애플리케이션 컨텍스트 등록

  • 서블릿 이벤트 리스너 사용
  • 웹 애플리케이션의 시작과 종료 시 발생하는 이벤트를 처리하는 리스너를 사용한다.
  • ContextLoaderListner : 웹 애플리케이션이 시작될 때 루트 애플리케이션 컨텍스트를 만들어 초기화하고, 웹 애플리케이션이 종료될 때 컨텍스트를 함께 종료하는 기능
  • web.xml 파일에 리스터 선언하면 됨.

서블릿 애플리케이션 컨텍스트 등록

  • 스프링 웹 기능을 지원하는 프론트 컨트롤러 서블릿은 DispatcherServlet이다.
  • 서블릿이 초기화 될 때 컨텍스트를 생성하고 초기화. 웹 애플리케이션 레벨에 등록된 루트 애플리케이션 컨텍스트를 찾아서 부모 컨텍스트로 사용

1.2 IOC/DI를 위한 빈 설정 메타 정보 작성

1.2.1

자동인식을 이용한 빈 등록: 스테레오타입 애노테이션과 빈 스캐너

  • XML 문서와 같이 한곳에 명식적ㅇ로 선언하지 않고도 스프링 빈을 등록하는 방법이 있다.
  • 빈으로 사용될 클래스에 특별한 애노테이션을 부여해주면 이런 클래스를 자동으로 차장서 빈으로 등록해주게 할 수 있다.

빈스캐닝 : 특정 애노테이션이 붙은 클래스를 자동으로 찾아서 빈으로 등록
빈 스캐너: 스캐닝 작업 담당

스테레오타입 애노테이션

  • @Component, @Component를 메타 애노테이션으로 가진 애노테이션
  • @Repository
  • @Service
  • xml을 이용해서 빈 스캐너를 등록할 수도 있다.
  • 빈 스캐너를 내장한 애플리케이션 컨텍스트 사용하는 방법도 있다.

자바 코드에 의한 빈 등록: @Configuration 클래스의 @Bean 메소드

  • @Configuration과 @Bean이 붙으면 스프링 컨테이너가 인식할 수 있는 빈 메타정보 겸 빈 오브젝트 팩토리가 된다.

0개의 댓글