2

Glassfish 3.1.1 で、単一の SFSB を ViewScoped JSF バッキング Bean に注入しようとしています。

私のログはこれを示しています.2つのSFSBが作成されています.

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@f48cde0
INFO: constructed a new sfsb: com.exmaple.test.service.impl._TestSFSBImpl_Serializable@13dbf5ce
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@4de6b191

その後、別の場所に移動して ViewScoped Bean が範囲外になったときに、SFSB で remove() を呼び出すと、ログに次のように表示されます。

INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@4de6b191
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@13dbf5ce
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@13dbf5ce

しかし、@ f48cde0 で終わる余分な最初のものは決して注入されなかったので、私はそれに対するハンドルを持っておらず、削除されることはありません。後でサーバーをシャットダウンすると、サーバーが削除されていることがわかります。

これが私のコードです:

バッキング Bean:

package com.example.test.ui;

import java.io.Serializable;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;

import com.example.test.service.api.TestSFSB;

@ManagedBean(name = "testViewScopedSFSB")
@ViewScoped
public class TestViewScopedSFSB implements Serializable {

  private static final long serialVersionUID = 1L;
  private static final Logger LOGGER = Logger.getLogger(TestViewScopedSFSB.class.getCanonicalName());

  @EJB
  private TestSFSB testSFSB;

  @PostConstruct
  public void postConstruct() {
    LOGGER.info("constructed a new view scoped bean: " + this);
  }

  public int getNumClicks() {
    return testSFSB.getNumClicks();
  }

  public void clicked(AjaxBehaviorEvent event) {
    testSFSB.clicked();
  }

  @PreDestroy
  public void preDestroy() {
    LOGGER.info("destroying view scoped bean: " + this);
    testSFSB.remove();
  }

}

SFSB インターフェース:

package com.example.test.service.api;

public interface TestSFSB {

  void clicked();

  int getNumClicks();

  void remove();

}

SFSB の実装:

package com.example.test.service.impl;

import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Local;
import javax.ejb.Remove;
import javax.ejb.Stateful;

import com.example.test.service.api.TestSFSB;

@Stateful
@Local(TestSFSB.class)
public class TestSFSBImpl implements TestSFSB {

  private static final long serialVersionUID = 1L;
  private static final Logger LOGGER = Logger.getLogger(TestSFSBImpl.class.getCanonicalName());

  int numClicks = 0;

  @PostConstruct
  public void postConstruct() {
    LOGGER.info("constructed a new sfsb: " + this);
  }

  @Override
  public void clicked() {
    numClicks++;
  }

  @Override
  public int getNumClicks() {
    return numClicks;
  }

  @Override
  @Remove
  public void remove() {
    LOGGER.info("removing sfsb: " + this);
  }

  @PreDestroy
  public void preDestroy() {
    LOGGER.info("destroying sfsb: " + this);
  }

}

最後に、jsf ページ:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<h:html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>

</h:head>

<h:body>
    <h:form>
        <h:commandLink action="/public/publicResource.jsf" value="Home" />
        <h:panelGrid id="panel1">
            <h:commandButton value="Click me">
                <f:ajax event="click" listener="#{testViewScopedSFSB.clicked}"
                    render="panel1" />
            </h:commandButton>
            <h:outputText value="#{testViewScopedSFSB.numClicks}" />
        </h:panelGrid>
    </h:form>

</h:body>
</h:html>

これは非常に単純な設定です...一体何ができるのでしょうか? おそらくGlassfishのバグ?

編集: 私が報告していることの真実性についての「疑い」を和らげるために、ページを10回ロードしたときのログを次に示します。毎回 2 つずつ作成された 20 個の SFSB に注意してください。

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@561b0019
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@2767c7d9
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@7b239469
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@7b239469
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@2767c7d9
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@2767c7d9

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5c8608b9
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@63a6d923
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@5ef9bbf1
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@5ef9bbf1
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@63a6d923
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@63a6d923

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@31a4ef37
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@43551d57
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@8f95d4a
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@8f95d4a
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@43551d57
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@43551d57

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@69e3f60e
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5f91e550
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@63661834
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@63661834
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5f91e550
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5f91e550

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@266c4c10
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@ff5c225
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@4f9d1352
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@4f9d1352
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@ff5c225
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@ff5c225

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@42650c3b
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7806178a
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@57f3a295
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@57f3a295
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7806178a
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7806178a

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@70879d38
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5763013f
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@24e6fbeb
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@24e6fbeb
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5763013f
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5763013f

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@49649260
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@552ee43b
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@798a092d
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@798a092d
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@552ee43b
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@552ee43b

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@1a722605
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@3c1e1fd3
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@5dbb747a
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@5dbb747a
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@3c1e1fd3
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@3c1e1fd3

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@21da38c0
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7dc3d69c
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@443edc45
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@443edc45
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7dc3d69c
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7dc3d69c

そして最後に、アプリをアンロードすると、10 個の余分な SFSB が最終的に破棄されることに注意してください。

INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@561b0019
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5c8608b9
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@31a4ef37
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@69e3f60e
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@266c4c10
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@42650c3b
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@70879d38
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@49649260
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@1a722605
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@21da38c0

同じパターンで 200 の Bean を引き起こす 100 のヒットに対して動作が保持されるという私の評判に基づいて、私の言葉を信じてください。

4

1 に答える 1

0

これはバグではなく、機能です。そして、重要なもの。Java EE では、コンテナはさまざまなもの (ステートレス Bean、メッセージ駆動型 Bean、エンティティ、sfsbs など) のいくつかのインスタンスを作成し、それらをプールしてキャッシュします。これをコンテナーに任せて処理することが、Java EE を使用する理由の 1 つです。この動作は、ほとんどのコンテナーで構成できます。

Glassfish のドキュメントから:

さらに、GlassFish Server は、キャッシュされる「ステートフル」インスタンス (ステートフル セッション Bean およびエンティティ Bean) の数とそれらがキャッシュされる期間を制御できる多数の調整可能なパラメータをサポートします。

[..]

GlassFish Server プーリングの最も重要なパラメータの 1 つは、steady-pool-size です。steady-pool-size が 0 より大きい値に設定されている場合、コンテナーは、指定された数の Bean を Bean プールに事前設定するだけでなく、この数の Bean がフリー プールで常に使用可能であることを確認しようとします。これにより、ユーザー要求を処理するのに十分な数の Bean が準備完了状態にあることが保証されます。

( http://docs.oracle.com/cd/E18930_01/html/821-2418/beahn.html#beahq )

この動作が望ましくない場合は、構成を解除できます。上記のリンクから適切なリンクを読んでたどってください。

于 2012-03-27T18:07:46.233 に答える