동일한 세션에 대해 두 개의 SessionScoped CDI Bean 인스턴스가 있습니다. 나는 CDI가 나를 위해 생성 한 인스턴스가 하나 있다는 인상하에 있었지만, 두 개를 생성했습니다. CDI 작동 방식을 잘못 이해했거나 버그를 찾았습니까?CDI SessionScoped Bean은 동일한 세션에서 두 개의 인스턴스가됩니다.
여기<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<f:view contentType="text/html" encoding="UTF-8">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form id="form">
<h:inputText value="#{myBean.myField}"/>
<h:commandButton value="Submit"/>
</h:form>
</h:body>
</f:view>
</html>
배치에서 출력되는 페이지를 탐색 :
INFO: Loading application org.mycompany_myproject_war_1.0-SNAPSHOT at /myproject
INFO: org.mycompany_myproject_war_1.0-SNAPSHOT was successfully deployed in 8,237 milliseconds.
INFO: MyBean constructor called
INFO: Session ID: 175355b0e10fe1d0778238bf4634
INFO: MyBean constructor called
INFO: Session ID: 175355b0e10fe1d0778238bf4634
글래스 피시 사용
여기package org.mycompany.myproject.session;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.http.HttpSession;
@Named @SessionScoped public class MyBean implements Serializable {
private String myField = null;
public MyBean() {
System.out.println("MyBean constructor called");
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession)fc.getExternalContext().getSession(false);
String sessionId = session.getId();
System.out.println("Session ID: " + sessionId);
}
public String getMyField() {
return myField;
}
public void setMyField(String myField) {
this.myField = myField;
}
}
가 Facelet 코드 : 여기
는 빈 코드 3.0.1
strub : 생성자 (또는 초기화 블록)의 비 마지막 메소드 호출은 CDI와 의도하지 않은 효과를 야기한다. 그 이후로 비 최종 메소드를 사용하는 것이 권장되지 않는다는 것을 읽었습니다 (http://download.oracle.com/javase/tutorial/java/javaOO/initial.html). 비 최종 메소드를 사용하여 CDI 빈에서리스트를 초기화하면 intitializer가 두 번 호출됩니다! 주 : CDI는 최종 메소드를 허용하지 않으며 bean이 프록시 가능하지 않다는 것을 나타내는 런타임 예외를 발생시킵니다. "수정"은 비 최종 메서드를 호출하지 않고 initilizer 블록에서 모두 작업하는 것입니다. – Ryan
@PostConstruct로 주석 처리 된 init 메소드를 정의하는 경우 (생성되는 두 개의 빈 인스턴스에도 불구하고) 한 번만 호출된다는 것을 알았습니다. CDI가 빈의 인스턴스 풀을 생성하고 풀에서 풀을 생성 할 때 post 구조를 호출하는 것으로 추측합니다. 아직 풀에있는 빈 인스턴스를 현재 HTTP 세션과 연관시키는 것은 의미가 없다고 생각합니다. – Ryan
아래 나의 대답을 참조하십시오. 첫 번째 인스턴스는 상황 별 인스턴스이고 두 번째 인스턴스는 프록시입니다. @PostConstruct는 당연히 컨텍스트 인스턴스에 대해서만 호출되고 프록시에 대해서는 _not_이됩니다. – struberg