5

同じセッションにSessionScopedCDIBeanのインスタンスが2つあります。CDIによって生成されたインスタンスは1つであるという印象を受けましたが、2つ生成されました。CDIがどのように機能するかを誤解していますか、それともバグを見つけましたか?

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>

デプロイメントとページへのナビゲートからの出力は次のとおりです。

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

GlassFish3.0.1の使用

4

2 に答える 2

6

ライアン、コベナーがすでに書いたように、コンストラクターはそのBeanのすべてのプロキシーに対しても呼び出されます。これは、インターフェイスプロキシ(java.lang.reflect.proxyのものなど)だけでなく、実際のクラスプロキシを提供するすべてのプロキシメカニズムの標準的な動作です。

また、ctはすべてのシリアル化に対しても呼び出されることを想像してください。したがって、負荷分散の激しいクラスターで作業している場合は、これが何度も発生します。したがって、一般的にBeanには@PostConstructを使用してください。

LieGrue、スタブ

于 2011-06-24T22:42:20.577 に答える
3

CDI実装は、インジェクションポイントに使用するプロキシを更新するときに、基になるBeanのデフォルトコンストラクターを呼び出す可能性があります。これは、weldおよびopenwebbeansで使用されるjavassistのデフォルトの動作です。

可能であれば、デフォルトのコンストラクターを@PostConstructに移動して、手間のかかる作業を避けてください。

于 2011-01-04T19:49:33.930 に答える