3

ChartBeanPrimeFaces のサンプルを使用しようとしています。これはビューです:

<h:form>
    <p:layoutUnit position="center">             
    <p:lineChart id="linear" value="#{chartBean.linearModel}" legendPosition="e"
        title="Linear Chart" minY="0" maxY="1000" style="height:600px"/>                        
    </p:layoutUnit>
</h:form>

これは豆です:

@Named
@RequestScoped
public class ChartBean implements Serializable {

    private CartesianChartModel categoryModel;
    private CartesianChartModel linearModel;

    public ChartBean() {
        System.out.println("ChartBean constructed");
        createCategoryModel();
        createLinearModel();
    }

    // ...
}

実行中に、この Bean のコンストラクターがページを開くときに 2 回呼び出されることに気付きました。ログには次のように表示されます。

INFO: ChartBean が構築されました
INFO: ChartBean が構築されました

そのため、Bean は 2 回インスタンス化されました。これはどのように発生し、どうすれば回避できますか? UI に表示するデータを取得するために DB と対話していますが、この方法ではデータが不必要に 2 回フェッチされます。

4

1 に答える 1

12

最初の作成は、Bean のスコープ付きプロキシを作成するコンテナです。スコープ付きプロキシは、Bean を拡張し、他のコンポーネントが Bean を必要とするたびに注入されるオブジェクトです。ただし、メソッドは実際のロジックを実行するのではなく、Bean の正しいコンテキスト インスタンスに実行を委譲します。例を挙げて説明します:

2 つの要求、R1、R2 を想定します。ChartBeanB1 と B2の 2 つのインスタンスが必要です。別のコンポーネント C が に依存しているとしChartBeanます。アプリケーションの初期化時に C の関連フィールドに のインスタンスを注入し、ChartBean実行時に正しい Bean インスタンスを呼び出す必要があります。しかし、アプリの初期化時にはリクエストはなく、B1、B2 もありません。コンテナは何をしますか?スコープ付きプロキシを作成し、それを必要とする人に注入します。次に、ChartBean.method()が呼び出されるたびに、どの Bean を呼び出すのが正しいかを決定するプロキシで呼び出されます (R1 の場合は B1、R2 の場合は B2、たとえば a から呼び出されるアクティブなリクエストがない場合は例外をスローしますMessageDrivenBean)。

前述のとおり、コンストラクターはシステム/コンテナーから呼び出される可能性があるため、DO NOT RUN BUSINESS LOGIC IN CONSTRUCTORS IN JAVA EE COMPONENTSです。@PostConstruct代わりにメソッドを使用してください:

...
public class ChartBean implements Serializable {
    public ChartBean() {
        // only construction logic here
    }
    ...
    @PostConstruct
    void postConstruct() {
        createCategoryModel();
        createLinearModel();
    }
}

ちなみに、コンストラクターでクラス名を出力することにより、コンストラクターがプロキシ実装から呼び出されていることを確認できます。

    public ChartBean() {
        System.out.println("ChartBean as " + this.getClass().getName());
    }

初めて呼び出されたときは、自分のクラスとは別のクラスになります。

于 2013-09-20T08:17:48.580 に答える