簡體   English   中英

CDI SessionScoped Bean在同一會話中產生兩個實例

[英]CDI SessionScoped Bean results in two instances in same session

我有兩個SessionScoped CDI bean實例用於同一個會話。 我的印象是CDI會為我生成一個實例,但它產生了兩個。 我誤解了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

使用GlassFish 3.0.1

Ryan,正如covener已經寫過的那樣,構造函數也將被調用該bean的每個代理。 這是所有代理機制的標准行為,它不僅提供接口代理(如java.lang.reflect.proxy東西),而且提供真正的類代理。

還想象一下,每個序列化也會調用ct。 因此,如果您在負載均衡的集群上工作,您會看到很多次。 所以請一般使用@PostConstruct for beans。

LieGrue,strub

在新建代理用於注入點時,CDI實現可能會調用底層bean默認構造函數 - 這是javassist的默認行為,用於焊接和openwebbeans。

在默認構造函數中避免繁重的工作,如果可以的話,將它移動到@PostConstruct中!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM