관리 메뉴

공부한것들을 정리하는 블로그 입니다.

토비의스프링3.1 2권 1장. IoC 컨테이너와 DI 본문

Spring/공부

토비의스프링3.1 2권 1장. IoC 컨테이너와 DI

호 두 2022. 8. 2. 18:52
반응형

토비의스프링3.1 2권 1장. IoC 컨테이너와 DI


우선 핵심내용인 scope에 대해서 다루고
나머지 내용은 추후 작성


1.3 프로토타입과 스코프

1.3.1 프로토타입 스코프
 - 스코프는 존재할 수 있는 범위를 가리키는 말이다. 
 - 빈의 스코프는 빈 오브젝트가 만들어져 존재할 수 있는 범위다. 

싱글톤
 - 기본적으로 스프링의 빈은 싱글톤으로 만들어진다. 
 - 즉, 애플리케이션 컨텍스트마다 빈 오브젝트는 한 개만 만들어진다.


빈 오브젝트의 생명주기
 - 빈 오브젝트의 생명주기는 스프링 컨테이너가 관리하기 때문에 대부분 정해진 범위의 끝까지 존재한다. 


싱글톤 스코프의 생명주기
 - 싱글톤 스코프는 컨테이너 스코프라고 하기도 한다. 단일 컨테이너 구조에서는 컨테이너가 존재하는 범위와 싱글톤이 존재하는 범위가 일치하기 때문이다.
 - 요청(request) 스코프는 하나의 요청이 끝날때 까지만 존재한다.
 - 싱글톤 스코프는 컨텍스트당 한 개의 오브젝트만 만들어지게 함
 - 하나의 빈을 여러 개의 빈에서 DI하더라도 매번 동일한 오브젝트가 주입 (DI, getBean(), 등)
   - 하나의 빈을 여러 개의 빈에서 DI 하더라도 매번 동일한 프로젝트가 주입된다.


프로토타입 스코프
 - 싱글톤이 default인 스프링의 빈이지만, scope=prototype으로 설정시 다른 방식으로 적용 가능 (스프링이 빈을 생성은 하지만 관리를 하지 않음)
 - 프로토타입 스코프는 컨테이너에게 빈을 요청할 때마다 매번 새로운 오브젝트를 생성 (new 연산자를 이용한 오브젝트 생성 방식과 동일)


프로토타입 빈의 생명주기와 종속성
 - 스프링이 관리하는 빈은 의존관계 주입, 초기화, DI와 DL을 통한 사용, 제거까지 모든 오브젝트의 생명주기를 컨테이너가 관리
 - 프로토타입 빈은 독특하게 이 IoC의 기본 원칙을 따르지 않음 (생성, 초기화 DI가지만 제공)
 - 빈 오브젝트의 관리는 전적으로 DI 받은 오브젝트에 의존 (빈을 주입받은 오브젝트에 종속적)
 - DL 방식으로 직접 컨테이너에 getBean() 으로 프로토타입 빈을 요청한다면 요청한 코드가 유지시켜주는 만큼 빈 오브젝트가 존재 (메소드가 끝나면 프로토타입 빈도 제거)


* DL(Dependency Lookup) : 의존성 검색
 - Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용하여 Bean을 찾는 것을 의미한다.



프로토타입 빈의 용도
 - 프로토타입 빈은 new로 오브젝트를 생성하는 것을 대신하기 위해 사용
 - 사용자의 요청별로 독립적인 정보나 작업 상태를 저장해둘 오브젝트가 필요한 경우
 - 드물지만 컨테이너가 오브젝트를 만들고 초기화해줘야 하는 경우


사용 예시 
 - 콜센터 고객의 A/S 신청을 받아 접수하는 기능
   - 매번 신청을 받을때 마다 새롭게 만들어지며 폼의 정보를 담아서 서비스 계층에 전달
   - 접수된 내용을 DB에 저장하고 신청한 고객에게 이메일을 발송하는 로직 (서비스 계층)

장점
 - 처음 설계하고 만들기 편리하다는 점
단점
 - 폼의 고객정보 입력 방법이 모든 계층의 코드와 강하게 결합되어 있다는 점


오브젝트 중심의 구조(객체지향적)으로 변경하는 방법
 - 도메인 오브젝트 방식
   - ServiceRequestService는 ServiceRequest 오브젝트에 서비스 요청 내역과 함께 서비스를 신청한 고객정보를 Customer 오브젝트로 전달받아 사용
   - 의존성 주입 방식을 사용
     - 폼에서 문자열로 된 고객번호를 Customer 오브젝트로 바꿔서 ServiceRequest에 넣는 방법
   
 - 도메인 계층 방식
   - 마찬가지로 적용 가능할듯?


DI와 DL
 - DL은 ApplicationContext를 이용해 getBean()을 호출하는 방식을 의미


프로토타입 빈의 DL 전략
 - 스프링은 프로토타입 빈처럼 DL 방식을 코드에서 사용해야 할 경우 ApplicationContext 이용하는 것 외에도 다양한 방법을 제공
   - ApplicationContext, BeanFactory
   - ObjectFactory, ObjectFactoryCreatingFactoryBean

ServiceLocatorFactoryBean
 - ObjectFactory처럼 스프링이 미리 정의한 인터페이스를 사용하지 않아도 됌
 - DL 방식으로 가져올 빈을 리턴하는 임의의 이름을 가진 메소드가 정의된 인터페이스가 필요

메소드 주입
 - ApplicationContext는 스프링 API에 의존적인 코드를 만드는 불편함
 - ObjectFactory, ServiceLocatorFactoryBean을 사용하면 깔끔해지지만, 빈을 새로 추가가 필요
 - 메소드 주입은 두 가지 단점을 모두 극복해주는 DL 전략
   - 메소드 주입은 메소드를 통한 주입이 아니라 메소드 코드 자체를 주입하는 것을 의미
   - 새로운 프로토타입 빈을 가져오는 기능을 담당하는 메소드를 런타임 시에 추가해주는 기술

Provider<T>
 - @Inject와 함께 추가된 표준 인터페이스인 Provider를 이용하는 방법



1.3.2 스코프

스코프의 종류
 - 스프링은 싱글톤, 프로토타입 외에 
 - 4가지 스코프를 기본적으로 제공
   - 요청, 세션, 글로벌세션, 애플리케이션
   - 단, 웹 환경에서만 의미

요청 스코프
 - 요청 스코프 빈은 하나의 웹 요청 안에서 만들어지고 해당 요청이 끝날때 제거
 - 각 요청별로 독립적인 빈이 만들어지므로 빈 오브젝트 내에 상태 값을 저장해도 안전
 - 요청 스코프 빈은 프로토타입과 마찬가지로 DL이 편리하지만 DI도 이용 가능
 - 주요 용도는 애플리케이션 코드에서 생성한 정보를 프레임워크 레벨의 서비스나 인터셉터 등에 전달
 - 파라미터로 전달할 필요는 없지만 필요한 곳에서 참조해야 할 때 유용
 - 과용하면 전역변수를 사용하는 것처럼 코드를 이해하기 힘듬

세션 스코프, 글로벌세션 스코프
 - HTTP 세션과 같은 존재 범위를 갖는 빈을 만들어주는 스코프
 - HTTP 세션은 사용자별로 만들어지고 브라우저를 닫거나 세션 종료되기 전까지 정보를 유지
 - 웹 환경에 종속적인 HttpSession 오브젝트를 다른 계층으로 넘겨서 사용하는건 나쁜 방법
 - 세션 스코프를 이용하면 HTTP 세션에 저장되는 정보를 모든 계층에서 안전하게 이용
 - 글로벌세션 스코프는 포틀릿에만 존재하는 글로벌 세션에 저장되는 빈

애플리케이션 스코프
 - 애플리케이션 스코프는 서블릿 컨텍스트에 저장되는 빈 오브젝트
 - 서블릿 컨텍스트는 웹 애플리케이션마다 생성되고, 웹 애플리케이션마다 스프링 애플리케이션도 생성
 - 애플리케이션 스코프는 컨텍스트가 존재하는 동안 유지되는 싱글톤 스코프와 비슷한 존재 범위
 - 애플리케이션 스코프가 존재하는 이유는 웹 애플리케이션과 애플리케이션 컨텍스트의 존재 범위가 다른 경우가 있기 때문
 - 싱글톤 스코프와 마찬가지로 상태를 갖지 않거나 상태가 있더라도 읽기 전용으로 만들어야하며, 멀티스레드 환경에서 안전하도록 만들어야 함



스코프 빈의 사용 방법
 - 애플리케이션 스코프
   - 스코프와 비슷한 생명주기를 가지며 한 개만 생성/관리

 - 요청, 세션, 글로벌세션 스코프
   - 프로토타입 빈과 마찬가지로 한 개 이상의 빈 오브젝트가 생성/관리
   - 프로토타입 빈과는 다르게 스프링이 생성부터 초기화, DI, DL 제거까지 전 과정을 관리
     - 컨테이너가 정확하게 언제 새로운 빈이 만들어지고 사용될지 파악이 가능하기 떄문
     - 그러나 프로토타입과 마찬가지로 빈마다 하나 이상의 오브젝트가 만들어져야 하므로 싱글톤에 DI 해주는 방법은 사용 못함

 - 스코프 빈은 프로토타입 빈과 마찬가지로 Provider나 ObjectFactory 같은 DL 방식을 사용
 - 스코프 빈은 싱글톤에서 일반적인 방법으로 DI 하는 것은 불가능, 그 대신 스프링이 제공하는 특별한 DI 방법을 이용하면 DI처럼 사용 가능
직접 스코프 빈을 DI 하는 대신 스코프 빈에 대한 프록시를 DI 하여 사용


사용 예시 (세션 스코프 빈)
 - 로그인한 사용자의 정보를 HTTP 세션 안에 유지하는 예제 (DL 방식)
   - 세션 스코프
 - 스코프 빈을 DI방식으로 사용하려면 프록시의 도움이 필요
   - 스코프 프록시
 - 스코프 프록시는 각 요청에 연결된 HTTP 세선정보를 참고해서 사용자마다 다른 LoginUser 오브젝트를 사용하도록 해줌
 - 로그인 후 세션이 유지되는 동안에는 같은 오브젝트에 접근 할 수 있으므로 어느 페이지에서든 로긍니 정보를 참조 가능


반응형
Comments