어떻게 작동합니까?
JSF보기 (Facelets / JSP 파일)가 빌드 / 복원되면 JSF 컴포넌트 트리가 생성됩니다. 그 순간 뷰 빌드 시간 , 모든 binding
속성이 평가됩니다 ( JSTL과 같은 속성 및 태그 핸들러와 함께id
). 구성 요소 트리에 추가하기 전에 JSF 구성 요소를 만들어야하는 경우 JSF는 binding
속성이 미리 생성 된 구성 요소 (예 : non- null
)를 반환 하는지 확인한 다음 사용합니다. 미리 생성되지 않은 경우 JSF는 구성 요소를 "일반적인 방법"으로 binding
자동 생성하고 자동 생성 된 구성 요소 인스턴스를 인수로 사용하여 속성 뒤에 setter를 호출합니다 .
실제로 구성 요소 트리의 구성 요소 인스턴스 참조를 범위 변수에 바인딩합니다. 이 정보는 구성 요소 자체의 생성 된 HTML 표현에 표시되지 않습니다. 이 정보는 어쨌든 생성 된 HTML 출력과 관련이 없습니다. 양식이 제출되고보기가 복원되면 JSF 구성 요소 트리가 처음부터 다시 작성되고 모든 binding
속성이 위 단락에서 설명한대로 다시 평가됩니다. 컴포넌트 트리가 재생성 된 후 JSF는 JSF보기 상태를 컴포넌트 트리로 복원합니다.
구성 요소 인스턴스는 요청 범위입니다!
알고 이해해야 할 중요한 것은 구체적인 구성 요소 인스턴스가 효과적으로 요청 범위가 지정된다는 것입니다. 모든 요청에 대해 새로 생성되며 해당 속성은 복원보기 단계 동안 JSF보기 상태의 값으로 채워집니다. 따라서 구성 요소를 지원 빈의 속성에 바인딩하는 경우 지원 빈은 절대적으로 요청 범위보다 더 넓은 범위에 있지 않아야 합니다. JSF 2.0 사양 3.1.5 장을 참조하십시오 .
3.1.5 구성 요소 바인딩
...
컴포넌트 바인딩은 종종 Managed Bean 생성 기능을 통해 동적으로 인스턴스화되는 JavaBeans와 함께 사용됩니다 (섹션 5.8.1“VariableResolver 및 기본 VariableResolver”참조). 응용 프로그램 개발자는 "요청"범위에서 구성 요소 바인딩식이 가리키는 관리 빈을 배치하는 것이 좋습니다. 이는 UIComponent 인스턴스가 단일 스레드 내부에서 실행되는 것에 의존하기 때문에 세션 또는 응용 프로그램 범위에 배치하려면 스레드 안전성이 필요하기 때문입니다. 구성 요소 바인딩을 "세션"범위에 배치 할 때 메모리 관리에 잠재적으로 부정적인 영향을 미칠 수도 있습니다.
그렇지 않으면 구성 요소 인스턴스가 여러 요청간에 공유 되어 뷰에 선언 된 유효성 검사기, 변환기 및 리스너가 이전 요청의 기존 구성 요소 인스턴스에 다시 연결되기 때문에 " 중복 구성 요소 ID "오류 및 "이상한"동작이 발생할 수 있습니다. 증상은 명확합니다. 구성 요소가 바인드 된 것과 동일한 범위 내에서 각 요청에 대해 한 번 더 여러 번 실행됩니다.
그리고 과부하 상태에서 (즉, 여러 다른 HTTP 요청 (스레드)이 동시에 매우 동일한 구성 요소 인스턴스에 액세스하고 조작하는 경우) 조만간 UIComponent.popComponentFromEL 또는 Java 스레드 에서 스레드가 멈춤 과 함께 애플리케이션 충돌에 직면 할 수 있습니다. Richfaces UIDataAdaptorBase 및 내부 HashMap 을 사용하거나 JSF가 뷰 상태 (예 : 스택 추적 표시 또는 메서드 등)를 저장하거나 복원하는 동안 JSF 구현 소스 코드에서 "이상한" IndexOutOfBoundsException
또는 ConcurrentModificationException
직접 오는 100 % CPU 사용률 .saveState()
restoreState()
binding
빈 속성에 사용 하는 것은 나쁜 습관입니다.
어쨌든 binding
이 방법을 사용 하면 요청 범위 빈에서도 전체 구성 요소 인스턴스를 빈 속성에 바인딩하는 것은 JSF 2.xa에서 매우 드문 사용 사례이며 일반적으로 모범 사례가 아닙니다. 디자인 냄새를 나타냅니다. 당신은 일반적으로보기 측에서 구성 요소를 선언하고 바인드 자신의 런타임과 같은 속성 value
, 그리고 아마도 다른 사람들이 좋아하는 styleClass
, disabled
, rendered
일반 콩 속성 등. 그런 다음 전체 구성 요소를 잡고 속성과 관련된 setter 메서드를 호출하는 대신 원하는 빈 속성을 정확하게 조작합니다.
구성 요소의 요구가 "동적으로 작성"할 때의 경우 정적 모델을 기반으로 더 나은 사용하는 것입니다 JSTL처럼보기 빌드시 태그를 필요한 경우에, 태그 파일 대신에, createComponent()
, new SomeComponent()
, getChildren().add()
어떤이 없습니다. 이전 JSP의 스 니펫을 JSF와 동등한 것으로 리팩터링하는 방법 도 참조하십시오 .
구성 요소의 요구가 "동적으로 렌더링"하는 경우 또는 동적 모델을 기반으로, 다음 그냥 사용 반복자 구성 요소를 ( <ui:repeat>
, <h:dataTable>
, 등). JSF 구성 요소를 동적으로 추가하는 방법 도 참조하십시오 .
복합 구성 요소는 완전히 다른 이야기입니다. 내부의 구성 요소 <cc:implementation>
를 백업 구성 요소 (예 :으로 식별되는 구성 요소) 에 바인딩하는 것은 완전히 합법적 <cc:interface componentType>
입니다. f : convertDateTime을 사용하여 시간과 분을 나타내는 두 개의 h : inputText 필드에 대한 ao Split java.util.Date 및 다음 을 사용하여 동적 목록을 구현하는 방법을 참조하십시오. JSF 2.0 복합 구성 요소?
binding
로컬 범위 에서만 사용
그러나 때로는 특정 구성 요소 내부에서 다른 구성 요소의 상태에 대해 알고 싶을 때가 있습니다. 작업 / 값 종속 유효성 검사와 관련된 사용 사례에서 더 자주 알 수 있습니다. 이를 위해 binding
속성을 사용할 수 있지만 빈 속성과 함께 사용할 수는 없습니다 . 로컬 EL 범위에서 고유 변수 이름을 이와 같이 binding
속성에 지정할 수 있으며 binding="#{foo}"
구성 요소는에서 UIComponent
사용할 수있는 참조로 직접 동일한 뷰의 다른 위치에서 렌더링 응답 중에 있습니다 #{foo}
. 다음은 이러한 솔루션이 답변에 사용 된 몇 가지 관련 질문입니다.
또한보십시오:
User.User(), User.getLink(), User.setLink(), User.getValue()
링크를 클릭 할 때 =User.User(), User.setLink()...