SeamFramework.orgCommunity Documentation
지금까지 범위 유형 어노테이션의 여러 가지 예를 살펴보았습니다. Web Bean의 범위는 Web Bean 인스턴스의 수명주기를 결정합니다. 또한 범위는 어떤 클라이언트가 어떤 Web Bean 인스턴스를 참조하게 할 지를 결정합니다. Web Beans 사양에 따라 범위는 다음을 결정합니다:
범위와 함께 Web Bean의 새로운 인스턴스가 생성될 시기
범위와 함께 Web Bean의 기존 인스턴스가 제거될 시기
삽입된 어떤 참조가 범위와 함께 Web Bean 인스턴스를 참조하는 지
예를 들어, Web Bean 세션 범위가 있을 경우, CurrentUser
, 동일한 HttpSession
컨텍스트에서 호출되는 모든 Web Beans는 동일한 CurrentUser
인스턴스를 확인하게 됩니다. 이러한 인스턴스는 세션에서 CurrentUser
가 처음으로 필요할 때 자동으로 생성되고 세션이 끝나면 자동으로 삭제됩니다.
Web Beans는 extensible context model을 특징으로 합니다. 새로운 범위 유형 어노테이션을 생성하여 새로운 범위를 정의할 수 있습니다:
@Retention(RUNTIME)
@Target({TYPE, METHOD})
@ScopeType
public @interface ClusterScoped {}
물론 이는 이러한 작업 중 쉬운 부분입니다. 이러한 범위 유형을 유용하게 하려면, 범위를 구현하는 Context
객체를 정의해야 합니다! Context
구현은 아주 기술적인 작업으로, 프레임워크 개발 만을 목적으로 합니다.
Web Bean 범위를 지정하기 위해 Web Bean 구현 클래스에 범위 유형 어노테이션을 적용할 수 있습니다:
@ClusterScoped
public class SecondLevelCache { ... }
주로, Web Beans의 내장된 범위 중 하나를 사용하게 됩니다.
Web Beans는 네 가지 내장된 범위를 정의합니다:
@RequestScoped
@SessionScoped
@ApplicationScoped
@ConversationScoped
Web Beans를 사용하는 웹 애플리케이션의 경우:
servlet 요청은 활성 요청, 세션 및 애플리케이션 범위에 액세스합니다
JSF 요청은 활성 컨버세이션 범위에 액세스합니다.
요청 및 애플리케이션 범위도 활성화되어 있습니다:
EJB 원격 방식의 호출시
EJB 시간 초과시
메세지 구동 빈에 메세지 전달시
웹 서비스 호출시
애플리케이션이 활성 컨텍스트가 없는 범위와 함께 Web Bean을 호출하고자할 경우, 런타임시 ContextNotActiveException
은 Web Bean 관리자에 의해 넘기게 됩니다.
네 개의 내장된 범위 중 세 개는 모든 Java EE 개발자에게 익숙하므로, 여기서 다루지 않겠습니다. 하지만 이 중 하나의 범위 새로운 것입니다.
Web Beans 컨버세이션 범위는 시스템 사용자와 관련된 상태를 보유하고 있는 전통 세션 범위와 유사하며, 서버에 여러 가지 요청을 보냅니다. 하지만, 세션 범위와 다르게 컨버세이션 범위는 다음과 같은 사항을 갖습니다:
애플리케이션에 의해 명시적으로 경계를 정합니다
JSF 애플리케이션에 있는 특정 웹 브라우저 탭과 관련한 상태를 유지합니다.
컨버세이션은 사용자 관점에서의 작업 단위, 작업 내용을 나타냅니다. 컨버세이션 컨텍스트는 현재 사용자가 작업하고 있는 것과 관련된 상태를 유지합니다. 사용자가 동시에 여러가지 작업을 실행하고 있을 경우, 여러 개의 컨버세이션이 있게 됩니다.
컨버세이션 컨텍스트는 JSF 요청 시 활성화되어 있습니다. 하지만 대부분의 컨버세이션은 요청 마지막에 삭제됩니다. 컨버세이션이 여러 가지 요청을 통해 상태를 유지해야 할 경우, 장기 실행 컨버세이션으로 요청되어야 합니다.
Web Beans는 JSF 애플리케이션에 있는 컨버세이션 수명 주기를 제어하기 위한 내장된 Web Bean을 제공합니다. 이러한 Web Bean은 삽입에 의해 획득될 수 있습니다:
@Current Conversation conversation;
장기 실행 컨버세이션으로의 최근 요청과 관련된 컨버세이션을 활성화하려면, 애플리케이션 코드에서 begin()
방식을 호출합니다. 현재 요청의 마지막에 삭제를 위해 장기 실행 컨버세이션 컨텍스트를 스케줄하려면 end()
를 호출합니다.
다음의 예에서, 컨버세이션 범위 Web Bean은 관련 된 컨버세이션을 제어합니다:
@ConversationScoped @Stateful
public class OrderBuilder {
private Order order;
private @Current Conversation conversation;
private @PersistenceContext(type=EXTENDED) EntityManager em;
@Produces public Order getOrder() {
return order;
}
public Order createOrder() {
order = new Order();
conversation.begin();
return order;
}
public void addLineItem(Product product, int quantity) {
order.add( new LineItem(product, quantity) );
}
public void saveOrder(Order order) {
em.persist(order);
conversation.end();
}
@Remove
public void destroy() {}
}
Web Bean은 Conversation
API를 사용하여 수명 주기를 제어할 수 있습니다. 하지만 일부 다른 Web Beans는 다른 객체에 완전히 의존하는 수명 주기를 갖습니다.
컨버세이션 컨텍스트는 JSF faces 요청 (JSF 양식 제출)과 함께 자동으로 보급됩니다. 예를 들어, 링크를 통한 네비게이션과 같이 이는 non-faces 요청과 함께 자동으로 보급되지 않습니다.
요청 매개 변수로서 컨버세이션의 고유 식별자를 포함하여 컨버세이션이 non-faces 요청과 함께 보급되도록 강제할 수 있습니다. Web Beans 사양은 이를 사용하기 위해 cid
라는 요청 매개 변수를 가집니다. 컨버세이션의 고유 식별자는 Conversation
객체에서 획득할 수 있으며, conversation
이라는 Web Beans 이름을 갖습니다.
따라서, 다음과 같은 링크가 컨버세이션을 보급합니다:
<a href="/addProduct.jsp?cid=#{conversation.id}" >Add Product</a >
Web Bean 관리자는 컨버세이션이 장기 실행으로 표시되어 있지 않아도, 리다이렉트를 통해 컨버세이션을 보급해야 합니다. 이는 "플래시" 객체와 같은 깨지기 쉬운 구조에 의지하지 않고 일반적인 POST-then-redirect 패턴 쉽게 구현하게 합니다. 이러한 경우 Web Bean 관리자는 리다이렉트 URL에 요청 매개 변수를 자동으로 추가합니다.
Web Bean 관리자에게는 리소스를 보관하기 위해 컨텍스트에 있는 모든 상태 및 컨버세이션을 삭제할 수 있는 권한이 있습니다. Web Bean 관리자 구현은 주로 시간 초과에 기반하여 이를 실행합니다 이는 Web Beans 사양에 의해 요청되지 않습니다. 시간 초과는 컨버세이션이 삭제된 후 비활성화 기간을 말합니다.
Conversation
객체는 시간 초과를 설정하기 위한 방식을 제공합니다. 이는 Web Bean 관리자에게 도움이 되며, 설정 사항을 무시하셔도 상관 없습니다.
conversation.setTimeout(timeoutInMillis);
네 가지 내장된 범위에 더하여, Web Beans는 dependent pseudo-scope라는 기능을 특징으로 합니다. 이는 범위 유형을 명시하지 않는 Web Bean에 대한 기본값 범위입니다.
예를 들어, Web Bean에는 @Dependent
범위 유형이 있습니다:
public class Calculator { ... }
Web Bean의 삽입 지점이 의존적 Web Bean을 해결할 때, 의존적 Web Bean의 새로운 인스턴스는 처음으로 Web Bean이 초기화될 때 마다 생성됩니다. 의존적 Web Beans의 인스턴스는 다른 Web Bean 사이에서나 또는 다른 삽입 지점 간에 공유되지 않습니다. 이는 일부 다른 Web Bean 인스턴스에 대해 의존적 객체입니다.
의존하는 인스턴스가 삭제되면 의존적 Web Bean 인스턴스가 삭제됩니다.
클래스 또는 EJB bean이 일부 다른 범위 유형과 함께 Web Bean으로 명시되어 있어도, Web Beans는 Java 클래스 또는 EJB bean의 의존적 인스턴스를 쉽게 획득할 수 있게 합니다.
내장된 @New
바인딩 어노테이션은 삽입 지점에서 의존적 Web Bean의 암시적 정의를 허용합니다. 다음과 같은 삽입 영역을 명시한다고 가정합시다:
@New Calculator calculator;
@Dependent
범위, @New
바인딩 유형, Calculator
API 유형, Calculator
구현 클래스, @Standard
배치 유형과 함께 Web Bean은 암시적으로 정의됩니다.
Calculator
가 다른 범위 유형과 함께 이미 명시되어 있어도 이는 사실입니다, 예:
@ConversationScoped
public class Calculator { ... }
다음의 삽입 속성은 다른 Calculator
인스턴스를 갖습니다:
public class PaymentCalc {
@Current Calculator calculator;
@New Calculator newCalculator;
}
calculator
영역에는 Calculator
의 컨버세이션 범위 인스턴스가 삽입되어 있습니다. newCalculator
영역에는 PaymentCalc
소유로 바운딩된 수명 주기와 함께 Calculator
의 새로운 인스턴스가 삽입되어 있습니다.
특히 이러한 기능은 다음 장에서 다루게 될 생산자 방식에서 유용합니다.