Architecture Details

Aspectran의 빈 스코프(Bean Scopes) 심층 분석

Aspectran의 IoC 컨테이너는 빈(Bean)의 생명주기를 관리하는 범위를 지정하는 스코프(Scope) 개념을 지원합니다. 스코프는 빈 인스턴스가 언제 생성되고, 얼마나 오래 유지되며, 어떻게 소멸되는지를 결정합니다. com.aspectran.core.context.rule.type.ScopeType enum 클래스에 정의된 4가지 표준 스코프를 제공합니다.

1. SINGLETON

  • 정의: 하나의 빈 정의에 대해 ActivityContext 내에서 단 하나의 인스턴스만 생성됩니다. 컨테이너가 초기화될 때 생성되며, 이후 해당 빈에 대한 모든 요청은 이 고유한 인스턴스를 공유하게 됩니다.
  • 생명주기: ActivityContext의 시작부터 종료까지 유지됩니다.
  • 내부 동작: BeanRegistry는 싱글톤 빈의 인스턴스를 내부 캐시(일반적으로 Map)에 저장합니다. 빈 요청이 오면, 먼저 캐시에서 해당 ID의 빈을 찾아보고, 존재하면 즉시 반환합니다. 존재하지 않으면 새로 생성하여 캐시에 등록한 후 반환합니다.
  • 주요 용도: 상태를 가지지 않는(stateless) 서비스 객체, DAO, 설정 클래스 등 스레드에 상관없이 공유되어야 하는 컴포넌트에 적합합니다.
  • 주의사항: 여러 스레드에서 동시에 접근하므로, 내부에 변경 가능한 상태(mutable state)를 가질 경우 반드시 동기화 처리를 통해 스레드 안전성(thread-safety)을 보장해야 합니다.
  • 설정 별칭: singleton

2. PROTOTYPE

  • 정의: 빈을 요청할 때마다 매번 새로운 인스턴스를 생성합니다. 싱글톤과 달리 인스턴스를 전혀 공유하지 않습니다.
  • 생명주기: 컨테이너는 프로토타입 빈의 생성과 의존성 주입까지만 관여합니다. 일단 빈이 생성되어 클라이언트 코드에 전달된 후에는 컨테이너의 관리에서 벗어납니다. 즉, 생성된 인스턴스의 소멸은 가비지 컬렉터(GC)에 의해 처리되며, @Destroy와 같은 소멸 관련 콜백 메서드는 호출되지 않습니다.
  • 내부 동작: BeanRegistry는 프로토타입 스코프의 빈에 대한 요청을 받을 때마다 BeanRule에 정의된 정보를 바탕으로 new 키워드를 통해 새로운 객체를 생성하고 의존성을 주입하여 반환합니다. 캐싱 과정이 없습니다.
  • 주요 용도: 상태를 가지는(stateful) 객체에 적합합니다. 각 요청마다 독립적인 상태를 유지해야 할 때 사용됩니다.
  • 주의사항: 매번 새로운 객체를 생성하므로 싱글톤에 비해 오버헤드가 발생할 수 있습니다.
  • 설정 별칭: prototype

3. REQUEST

  • 정의: 단일 요청(Request)의 생명주기 동안에만 유효한 단일 인스턴스를 생성합니다. 동일한 요청 내에서는 항상 같은 인스턴스가 반환되지만, 다른 요청에서는 새로운 인스턴스가 생성됩니다.
  • 생명주기: 요청이 시작될 때 생성되고, 해당 요청이 종료될 때 소멸됩니다.
  • 내부 동작: 이 스코프는 RequestAdapter를 지원하는 환경에서만 유효합니다. Activity가 시작될 때, RequestAdapter의 내부 저장소(일반적으로 Map)에 스코프 빈을 저장합니다. 동일 요청 내에서 빈을 다시 요청하면 이 저장소에서 찾아 반환합니다. 요청 처리가 끝나고 Activity가 소멸될 때, RequestAdapter에 저장된 모든 request-scoped 빈의 소멸 콜백이 호출됩니다.
  • 환경 제약: WebActivityTowActivity와 같이 RequestAdapter가 존재하는 웹 환경에서만 의미가 있습니다. ShellActivityDaemonActivity 같은 환경에서 이 스코프를 사용하려고 하면 UnsupportedBeanScopeException이 발생합니다.
  • 주요 용도: HTTP 요청과 관련된 데이터(예: 요청 파라미터, 사용자 인증 정보)를 처리하는 객체에 적합합니다.
  • 설정 별칭: request

4. SESSION

  • 정의: 단일 사용자 세션(Session) 내에서 유효한 단일 인스턴스를 생성합니다. 동일한 세션 내에서는 항상 같은 인스턴스가 반환되지만, 다른 세션에서는 새로운 인스턴스가 생성됩니다.
  • 생명주기: 세션이 처음 시작될 때 생성되고, 해당 세션이 만료(invalidate)될 때 소멸됩니다.
  • 내부 동작: 이 스코프는 SessionAdapter를 지원하는 환경에서만 유효합니다. SessionAdapter는 내부적으로 HttpSession이나 Aspectran의 자체 SessionManager를 감싸고 있으며, session-scoped 빈은 이 세션의 속성(attribute)으로 저장됩니다. 세션이 소멸될 때, 세션에 저장된 모든 session-scoped 빈의 소멸 콜백이 호출됩니다.
  • 환경 제약: WebActivityShellService에서 세션 기능을 활성화한 경우처럼 SessionAdapter가 존재하는 환경에서만 의미가 있습니다. 세션 기능이 없는 환경에서 사용 시 UnsupportedBeanScopeException이 발생합니다.
  • 주요 용도: 사용자별로 유지되어야 하는 데이터(예: 로그인 정보, 장바구니)를 관리하는 객체에 적합합니다.
  • 설정 별칭: session

5. 요약

스코프설명생명주기관리 주체주요 용도환경 제약
SINGLETON컨텍스트 내 유일한 인스턴스애플리케이션 전체BeanRegistry상태 없는 서비스, DAO없음
PROTOTYPE매 요청 시 새 인스턴스GC에 의해 관리BeanRegistry (생성만)상태 있는 객체없음
REQUEST요청 당 새 인스턴스단일 HTTP 요청RequestAdapter요청 관련 데이터 처리RequestAdapter 필요
SESSION세션 당 새 인스턴스단일 사용자 세션SessionAdapter사용자별 데이터 관리SessionAdapter 필요