11

おそらく私の質問は些細なものですが、これまでアプリケーションスコープBeanを使用したことはありません。データベースで時間のかかるトランザクションを実行する必要があるため、アプリケーションBeanが必要です。私の検索は私の好奇心をまったく満足させませんでした。理由はわかりませんが、Beanを初期化できなかったか(null)、アプリがクラッシュしました。だから私はアプリケーションスコープBeanを持っています

@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationContainer {
...
}

eager = trueアプリケーションサーバー(私はGlassFishを使用)が起動するたびにBeanを開始するようにJSFに指示することを読みました。

このアノテーションを付けるだけでBeanが初期化されることをいくつかの場所で読みました。私にとってはそうではありません...アプリケーションBeanを別のBeanに注入する場合は、@PostConstuctアノテーションを使用する必要があることを読んだ後

@ManagedBean
@SessionScoped
public class TestsBean implements Serializable {

    private static final long serialVersionUID = 1L;
    @ManagedProperty(value = "#{container}")
    private ApplicationContainer container;

    @PostConstruct
    public void init() {
    container.contructContainer();
    }

これにより、TestsBeanを注入した他のBeanでエラーが発生します...

  • サーバーの起動時にアプリケーションBeanが初期化された場合、サーバーは必要なアクションを実行するためにアプリケーションBeanの本体でどのメソッドを呼び出しますか?または、注入されたBeanでは、postconstructメソッドで実行されますか?

アプリケーションBeanを処理する適切な方法を教えてください。私は本当に混乱しています...

いつもありがとうございました!

4

2 に答える 2

29

2つの潜在的な間違いがあります。

まず、javadoc@ManagedBean(eager=true)にあるように、動作はアプリケーションスコープのJSFマネージドBeanでのみ機能します。したがって、パッケージを使用した場合にのみ機能します(したがって、パッケージは機能しません)。基本的に、Beanは、ELで初めて参照された後でのみではなく、Webアプリケーションの起動時に自動インスタンス化されることを意味します。@ApplicationScopedjavax.faces.beanjavax.enterprise.contexteager=true

次に、マネージドBean名は、JavaBeans仕様に従って、デフォルトで大文字と小文字を区別しない形式のクラス名になります。のようなマネージドBean名を明示的に指定しなかった@ManagedBean(name="container", eager=true)ため、マネージドBean名はデフォルトでに設定されますがapplicationContainer、それでも、#{container}の代わりにとして参照しようとしています#{applicationContainer}

直面している問題/エラーについては、まったく明確ではありません。例外が発生した場合は、絶対に読んで解釈する必要があります。理解できない場合は、質問のスタックトレースを含めて全体をコピーして貼り付けてください。つまり、それ自体が問題に対する全体的な答えを表しています。あなたはそれを解釈して理解する必要があります(または私たちはそれを素人の言葉で説明する必要があります)。あなたは本当にそれらを無視してはならず、それらが無関係な装飾であるかのようにそれらを質問から除外するべきです。ではない!

結局のところ、完全で適切なアプローチは、念のためにインポート宣言を完了し、デバッグ用の貧乏人のstdoutプリントも必要です。

package com.example;

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;

@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationContainer {

    public ApplicationContainer() {
        System.out.println("ApplicationContainer constructed");
    }

}
package com.example;

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class TestsBean implements Serializable {

    @ManagedProperty("#{applicationContainer}")
    private ApplicationContainer container;

    public TestsBean() {
        System.out.println("TestsBean constructed");
    }

    @PostConstruct
    public void init() {
        System.out.println("ApplicationContainer injected: " + container);
    }

    public void setContainer(ApplicationContainer container) {
        this.container = container;
    }

}
于 2013-01-05T14:57:15.477 に答える
0

同じ問題があり、@ BalusCコードを使用して解決したので、ここに追加するものがあると思います。

質問の著者は次のように述べています。

それを読んだ後、アプリケーションBeanを別のBeanに注入する場合は、@PostConstuctアノテーションを使用する必要があります

これはまさに私の問題でした。セッションBeanのinit()メソッドでApplication Beanを使用しなかったことを除いて、BalusCが彼の回答で行ったのと同じようにすべてを行いました。だから、私は追加しました

@ManagedBean
@SessionScoped
public class TestsBean implements Serializable {

@PostConstruct 
init(){
....
System.out.println("appbean session init size" + appbean.getPinovi().size());
....
} 

これは私がそれを機能させるためにしなければならなかったことです、ただappBeanをなんとかして使用するだけです。ハックのようですが...

于 2019-09-11T13:26:03.633 に答える