【问题标题】:@Stateless Session Bean acts as a @Singleton Bean@Stateless Session Bean 充当@Singleton Bean
【发布时间】:2012-05-03 21:28:53
【问题描述】:

我正在尝试使用 EJB 会话 Bean 的示例。我想看看他们的区别。我的基本项目图如下;

http://img109.imageshack.us/img109/8262/85220418.png

项目就像一个购物车。当我通过注入的 EJB 调用托管 bean 以获取添加的 Urun 对象的结果时,结果列表必须是最后一个 Urun 对象。因为我的 EJB 是 @Stateless bean。但是,当我运行应用程序时,它会保留所有新添加的 Urun 对象。但它是无状态的,它必须在每个动作中保留最后一个 Urun 对象。然后,当我在其他网络浏览器中打开应用程序页面时,它会列出之前添加的 Urun 对象列表。但是托管 bean 和 Ejb 在我的模型中是无状态的。但它是一个 Singleton bean。我的问题在哪里?

@Stateless
public class AlisverisSepetiEJB {

    List<Urun> urunler=new ArrayList<>();

    public List<Urun> getUrunler() {
        return urunler;
    }

    public void setUrunler(List<Urun> urunler) {
        this.urunler = urunler;
    }

    public void urunEkle(Urun urun){
        urunler.add(urun);
    }

}

@ManagedBean(name="bean")
@RequestScoped
public class JSFYonetimliNesne {

    public JSFYonetimliNesne(){
        System.out.println("Yönetimli nesne çalıştı");
    }

   @EJB
   AlisverisSepetiEJB alisverisSepeti;

   Urun urun=new Urun();
   List<Urun> urunler;


    public List<Urun> getUrunler() {
        return alisverisSepeti.getUrunler();
    }

    public void setUrunler(List<Urun> urunler) {
        this.urunler = urunler;
    }

    public Urun getUrun() {
        return urun;
    }

    public void setUrun(Urun urun) {
        this.urun = urun;
    }

    public void sepeteKoy(){
        alisverisSepeti.urunEkle(urun);
        urun=new Urun();
    }

}

public class Urun {

   String urunAdi;
   Long fiyat;
   Long gramaj;

    public Long getFiyat() {
        return fiyat;
    }

    public void setFiyat(Long fiyat) {
        this.fiyat = fiyat;
    }

    public Long getGramaj() {
        return gramaj;
    }

    public void setGramaj(Long gramaj) {
        this.gramaj = gramaj;
    }

    public String getUrunAdi() {
        return urunAdi;
    }

    public void setUrunAdi(String urunAdi) {
        this.urunAdi = urunAdi;
    }

}

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Alışveriş Sepeti</title>
    </h:head>
    <h:body>
        Alışveriş Sepeti
        <h:form>

            <h:panelGrid columns="2">
            <h:outputLabel value="Ürün adı : "/>
            <h:inputText value="#{bean.urun.urunAdi}"/>
            <h:outputLabel value="Ürün fiyatı : "/>
            <h:inputText value="#{bean.urun.fiyat}"/>
            <h:outputLabel value="ÜRün gramajı : "/>
            <h:inputText value="#{bean.urun.gramaj}"/>
            </h:panelGrid>

            <h:commandButton action="#{bean.sepeteKoy}" value="Sepete Ekle"/>

            <br><h:outputLabel value="Sepetteki Ürünler"/></br>


            <h:dataTable value="#{bean.urunler}" var="item" border="1">

            <h:column >
                <f:facet name="header">
                    <h:outputLabel value="Ürün adı"/>
                </f:facet>
            <h:outputText value="#{item.urunAdi}"/>
            </h:column>

            <h:column >
                <f:facet name="header">
                    <h:outputLabel value="Ürün fiyatı"/>
                </f:facet>
            <h:outputText value="#{item.fiyat}"/>
            </h:column>

            <h:column >
                <f:facet name="header">
                    <h:outputLabel value="Ürün gramajı"/>
                </f:facet>
            <h:outputText value="#{item.gramaj}"/>
            </h:column>

            </h:dataTable>

        </h:form>

    </h:body>
</html>

【问题讨论】:

  • 在 SO 上发帖时,请勿发布本地化源代码。

标签: java singleton ejb-3.0 stateless


【解决方案1】:

AlisverisSepetiEJB 的同一个实例很可能在调用之间共享(容器可以这样做,这是完全合法的)。正是因为@Stateless EJB 的无状态特性,您应该在其中声明实例属性!

删除List&lt;Urun&gt; urunler = new ArrayList&lt;&gt;(); 声明和所有关联方法,将无状态bean 视为其所有方法都是静态的类——这意味着它们不能使用任何实例属性并且必须完全独立于实例数据;如果需要在调用之间维护任何状态,则必须从调用 EJB 的位置将其作为参数传递。 @Stateless EJB 中唯一允许的实例变量是属性,它们本身是无状态的和/或不可变的。

如果您需要在调用之间维护购物车的状态,则必须将其保存在有状态的上下文中(例如,Web 应用程序的 Session 上下文)或将 EJB 标记为 @Stateful .

【讨论】:

  • 同意。如果你在 @Stateless bean 中有一些成员变量,它应该只是不包含任何“状态”信息的 EntityManager。
  • 无状态 bean 可能包含各种状态,除了用户可观察状态。因此,只要将它们用作内部缓存或性能优化,实体管理器,可能与某物的连接等都可以。
猜你喜欢
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-04
  • 2015-03-27
相关资源
最近更新 更多