同じセッションのSessionScoped CDI Beanのインスタンスが2つあります。私はCDIによって私のために生成されたインスタンスが1つありますが、2つ生成されたという印象を受けました。私はCDIの仕組みを誤解していますか、あるいはバグを見つけましたか?ここでCDI SessionScoped Beanは同じセッションで2つのインスタンスになります
は、Beanコードである:ここで
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コードです:ここで
<?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>
は、展開してページに移動するから出力さ:GlassFishのを使用して
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
3.0.1
strub:コンストラクタ(初期化子又はブロック)内の非最終的なメソッドを呼び出すは、CDIとの意図しない影響を引き起こします。私はそれ以来、非最終メソッドを使用することは推奨されていません(http://download.oracle.com/javase/tutorial/java/javaOO/initial.html)。 CDIのBeanでListを初期化するために非最終メソッドを使用すると、intitializerは2回呼び出されます。注意:CDIは最終的なメソッドを許可しておらず、Beanが代理可能ではないことを示すランタイム例外がスローされます。 "修正"は、非最終メソッドを呼び出さずに、すべてinitilizerブロックで作業することです。 – Ryan
@PostConstructでアノテーションされたinitメソッドを定義すると、(作成されるBeanの2つのインスタンスにもかかわらず)1回だけ呼び出されることに気付きました。私は、CDIが私のbeanのインスタンスのプールを作成していることを推測しています。私はプールに残っているBeanのインスタンスを現在のHTTPセッションに関連付けることは無意味だと思います。 – Ryan
下記の私の回答を参照してください。第1インスタンスはコンテキストインスタンス、第2インスタンスはプロキシです。 @PostConstructはもちろんコンテキストインスタンスに対してのみ呼び出され、_not_はプロキシに対して呼び出されます。 – struberg