올바른 콩 범위를 선택하는 방법?


답변:


485

소개

Bean의 범위 (수명)를 나타냅니다. 기본 서블릿 웹 애플리케이션의 "표지 아래"작업에 익숙한 경우 이해하기 쉽습니다. 서블릿은 어떻게 작동합니까? 인스턴스화, 세션, 공유 변수 및 멀티 스레딩 .


@Request/View/Flow/Session/ApplicationScoped

@RequestScoped빈은 긴 하나의 HTTP 요청 - 응답주기 등 (참고 단일 HTTP 요청으로 Ajax 요청 횟수도)로 살고있다. @ViewScoped당신이 전화 액션 메소드가 반환 포스트 백에 의해 같은 JSF보기와 상호 작용하고 같이 콩은 오래 살고 null/ void어떤 탐색 / 리디렉션하지 않고. @FlowScoped플로우 구성 파일에 등록 된 지정된보기 콜렉션을 탐색 하는 한 Bean이 존재합니다. @SessionScoped빈은 오래 설립 HTTP 세션 등으로 살고있다. @ApplicationScoped웹 애플리케이션이 실행되는 한 Bean이 존재합니다. CDI는 것을 참고 @Model기본적으로이다 관념 에 대한 @Named @RequestScoped동일한 규칙이 적용되도록.

선택할 범위는 Bean이 보유하고 나타내는 데이터 (상태)에만 의존합니다. 사용 @RequestScoped간단하고 비 아약스 양식 / 프리젠 테이션. 사용 @ViewScoped이 풍부한 동적 뷰 (ajaxbased 검증, 렌더링, 대화 상자 등) 아약스가 가능. @FlowScoped여러 페이지에 걸쳐 입력 데이터를 수집하는 "마법사"( "질문") 패턴에 사용하십시오 . @SessionScoped로그인 한 사용자 및 사용자 기본 설정 (언어 등)과 같은 클라이언트 특정 데이터에 사용 합니다. @ApplicationScoped모든 사람에게 동일한 드롭 다운 목록 또는 인스턴스 변수가없고 메소드 만있는 관리 Bean과 같은 애플리케이션 전체 데이터 / 상수에 사용하십시오 .

남용 @ApplicationScoped다른 사람이 그냥 일반 잘못이다 서로의 데이터를 볼 수 있도록, 모든 사용자와 공유 할 수 있도록 할 데이터가 세션 /보기 / 요청에 대한 빈 봐줘서. 남용 @SessionScoped뷰의 빈을 / 요청이 데이터는 모든 탭에서 공유 할 수 있도록 할 범위 / 단일 브라우저 세션에서 창, 사용자 경험에 대한 나쁜 탭 사이를 전환 한 후 모든보기와 상호 작용 할 때 최종 사용자가 inconsitenties가 발생할 수 있도록. 남용 @RequestScoped데이터 뷰 범위의 데이터를 만들어보기 위해 콩을 할 범주가 지정된 것은 아마도 작동하지 않는 형태를 일으키는 매 (아약스) 포스트 백에 기본값으로 초기화되는 ( 참조 또한 포인트 4, 5 여기 ). @ViewScoped요청, 세션 또는 애플리케이션 범위 데이터에 대해 Bean을 남용하고@SessionScoped 응용 프로그램 범위의 데이터에 대한 bean은 클라이언트에 영향을 미치지 않지만 불필요하게 서버 메모리를 차지하며 비효율적입니다.

실제로 메모리 사용량이 적고 상태를 완전히 유지하지 않으려는 경우가 아니라면 성능 영향에 따라 범위를 선택해서는 안됩니다 . @RequestScoped클라이언트의 상태를 유지하려면 요청 매개 변수와 함께 콩과 바이올린을 독점적으로 사용해야 합니다. 또한 범위가 다른 데이터가있는 단일 JSF 페이지가있는 경우 데이터의 범위와 일치하는 범위에서 별도의 백킹 Bean에 배치하는 것이 완벽하게 유효합니다. Bean은 @ManagedPropertyJSF 관리 Bean 또는 @InjectCDI 관리 Bean의 경우를 통해 서로 액세스 할 수 있습니다 .

또한보십시오:


@CustomScoped/NoneScoped/Dependent

그것은 귀하의 질문에 언급,하지만 (레거시) JSF는 지원 아니에요 @CustomScoped@NoneScoped거의 현실 세계에서 사용되지되는. 는 @CustomScoped사용자 정의를 참조해야 Map<K, Bean>오버라이드 (override)가 약간 더 넓은 범위에서 구현 Map#put()및 / 또는 Map#get()콩 생성을보다 세밀하게 제어 할 수 있습니다 및 / 또는 파괴의 순서를.

JSF @NoneScoped및 CDI는 @Dependent기본적으로 Bean에 대한 단일 EL 평가만큼 오래 지속됩니다. 빈 속성을 참조하는 두 개의 입력 필드와 빈 액션을 참조하는 명령 버튼이 총 3 개의 EL 표현식으로 이루어진 로그인 양식을 상상해보십시오. 그러면 실제로 3 개의 인스턴스가 만들어집니다. 하나는 사용자 이름이 설정되고 하나는 암호가 설정되고 다른 하나는 작업이 호출됩니다. 일반적으로이 범위는 주입되는 Bean만큼 지속되어야하는 Bean에서만 사용하려고합니다. 소위 경우 @NoneScoped또는이 @DependentA의 주입 @SessionScoped, 그것은만큼으로 살 것이다 @SessionScoped콩.

또한보십시오:


플래시 범위

마지막으로 JSF는 플래시 범위도 지원합니다. 세션 범위의 데이터 항목과 연관된 짧은 리빙 쿠키로 지원됩니다. 경로 재 지정하기 전에 세션 범위의 데이터 항목과 고유하게 연관된 값을 사용하여 HTTP 응답에 쿠키가 설정됩니다. 리디렉션 후 플래시 범위 쿠키가 있는지 확인하고 쿠키와 관련된 데이터 항목이 세션 범위에서 제거되고 리디렉션 된 요청의 요청 범위에 배치됩니다. 마지막으로 쿠키는 HTTP 응답에서 제거됩니다. 이렇게하면 리디렉션 된 요청이 초기 요청에서 준비된 범위 데이터 요청에 액세스 할 수 있습니다.

이것은 실제로 관리되는 Bean 범위로 사용할 수 없습니다. 즉와 같은 것은 없습니다 @FlashScoped. 플래시 범위는 ExternalContext#getFlash()관리 Bean 및 #{flash}EL을 통해 맵으로 만 사용할 수 있습니다 .

또한보십시오:


4
" JSF에서 뷰 범위 Bean이 언제 어떻게 파괴됩니까? " 라는 질문에 대한 귀하의 답변 에 대한 언급은 여기에 관련이 있다고 생각합니다 .
Lii

3
@Cold : 구식 CDI 범위이며 JSF 2.2로 대체됩니다 @FlowScoped(수동으로 시작 / 중지 할 필요 없음).
BalusC

1
그리고 DeltaSpike 추가로 가지고 ViewAccesscopedWindowScoped
Kukeltje

@BalusC, ViewScopedMyFaces 2.2의 bean에 문제가 있다고 생각 합니다. 나는 현재 여기에ViewScoped 게시 한 bean과 Ajax에 문제가 있습니다 . MyFaces JIRA에는 이 주제에 대한 토론 도 있습니다 .
Tapas Bose

CDI는 네 가지 기본 제공 범위를 정의합니다. @RequestScoped @SessionScoped @ApplicationScoped @ConversationScoped 설명하는 범위가 다른 이유는 무엇입니까?
Hosein Aqajani

122

JSF 2.3부터 패키지 javax.faces.bean패키지에 정의 된 모든 Bean 범위는 CDI와 범위를 맞추기 위해 더 이상 사용되지 않습니다. 또한 bean이 @ManagedBean주석을 사용하는 경우에만 적용 가능합니다 . 2.3 미만의 JSF 버전을 사용하는 경우 끝에있는 레거시 답변을 참조하십시오.


JSF 2.3부터는 JSF Backing Bean에서 사용할 수있는 범위가 있습니다.

1.@javax.enterprise.context.ApplicationScoped : 응용 프로그램 범위는 웹 응용 프로그램의 전체 기간 동안 지속됩니다. 해당 범위는 모든 요청과 모든 세션에서 공유됩니다. 전체 응용 프로그램에 대한 데이터가있을 때 유용합니다.

2.@javax.enterprise.context.SessionScoped : 세션 범위는 세션이 설정된 시간부터 세션 종료까지 지속됩니다. 세션 컨텍스트는 동일한 HTTP 세션에서 발생하는 모든 요청간에 공유됩니다. 이것은 특정 세션의 특정 클라이언트에 대한 데이터를 저장하지 않을 때 유용합니다.

3.@javax.enterprise.context.ConversationScoped : 대화 범위는 Bean이있는 동안 로그로 유지됩니다. 범위는 두 가지 방법을 제공 Conversation.begin()하고 Conversation.end(). 이 메소드는 Bean의 수명을 시작하거나 종료하기 위해 명시 적으로 호출해야합니다.

4.@javax.enterprise.context.RequestScoped : 요청 범위가 짧습니다. HTTP 요청이 제출 될 때 시작되고 응답이 클라이언트로 다시 전송 된 후 종료됩니다. 관리 Bean을 요청 범위에 배치하면 각 요청마다 새 인스턴스가 작성됩니다. 세션 범위 스토리지 비용이 염려되는 경우 요청 범위를 고려하는 것이 좋습니다.

5@javax.faces.flow.FlowScoped : 흐름 범위는 흐름이 지속되는 한 지속됩니다. 플로우는 작업 단위를 정의하는 포함 된 페이지 세트 (또는보기)로 정의 될 수 있습니다. 사용자가 흐름에서 탐색하는 한 흐름 범위가 활성화되었습니다.

6.@javax.faces.view.ViewScoped : 동일한 JSF 페이지가 다시 표시되는 동안 뷰 범위의 Bean이 지속됩니다. 사용자가 다른 페이지로 이동하자마자 Bean은 범위를 벗어납니다.


다음 레거시 답변은 2.3 이전의 JSF 버전에 적용됩니다.

JSF 2.x부터 4 개의 Bean 범위가 있습니다.

  • @SessionScoped
  • @RequestScoped
  • @ 응용 범위
  • @ViewScoped

세션 범위 : 세션 범위는 세션이 설정된 시간부터 세션 종료까지 지속됩니다. 웹 애플리케이션이 HttpSession 오브젝트에서 invalidate 메소드를 호출하거나 시간 종료되면 세션이 종료됩니다.

RequestScope : 요청 범위가 짧습니다. HTTP 요청이 제출 될 때 시작되고 응답이 클라이언트로 다시 전송 된 후 종료됩니다. 관리 Bean을 요청 범위에 배치하면 각 요청마다 새 인스턴스가 작성됩니다. 세션 범위 스토리지 비용이 염려되는 경우 요청 범위를 고려하는 것이 좋습니다.

ApplicationScope : 응용 프로그램 범위는 웹 응용 프로그램의 전체 기간 동안 지속됩니다. 해당 범위는 모든 요청과 모든 세션에서 공유됩니다. 웹 애플리케이션의 모든 인스턴스간에 단일 Bean을 공유해야하는 경우 관리 Bean을 애플리케이션 범위에 배치하십시오. Bean은 애플리케이션의 사용자가 처음 요청할 때 구성되며 웹 애플리케이션이 애플리케이션 서버에서 제거 될 때까지 활성 상태를 유지합니다.

ViewScope : JSF 2.0에서 뷰 범위가 추가되었습니다. 동일한 JSF 페이지가 다시 표시되는 동안 뷰 범위의 Bean이 지속됩니다. JSF 스펙은 JSF 페이지에 대해 용어보기를 사용합니다. 사용자가 다른 페이지를 탐색하자마자 Bean은 범위를 벗어납니다.

요구 사항에 따라 범위를 선택하십시오.

출처 : David Geary & Cay Horstmann의 Core Java Server Faces 3rd Edition [페이지 번호. 51-54] 여기에 이미지 설명을 입력하십시오


"HttpSession 객체의 invalidate 메소드"( invalidate()메소드 또는 유효하지 않은 메소드)의 의미는 무엇입니까?
Alexander Pozdneev

1
조금 오래되고 답글이 늦었지만 분명히하기 위해 FacesContext.getCurrentInstance().getExternalContext().invalidateSession();"로그 아웃 빈"에서 호출하는 것이 그가 의미하는 바입니다.
Roland

1
그것은 8 개의 범위가있는 순간에 레거시 답변이되었습니다
Ewoks

@KishorPrakash : 얼마 전 6 개월 전입니다. ;-)
Kukeltje '11.

@Kukeltje : 죄송합니다.
Kishor Prakash
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.