16

JSF マネージド Bean を自動的に作成することは可能ですか?

たとえば、いくつかのセッション スコープ Bean があります。これらのインスタンスに (JSF だけでなく) コードでアクセスすることが必要になる場合があります。これは、次の方法で行います。

PageBean pageBean = (PageBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("pages");

ただし、「#{pages}」を呼び出すページがまだアクセスされていない場合、これはnullに解決されます...スコープの「開始」時にJSFにBeanを作成させる方法はありますか? この場合、理想的には、ユーザー セッションが開始されたときに「ページ」Bean がセッションですぐにインスタンス化されるのでしょうか?

4

4 に答える 4

27

Application#evaluateExpressionGet()代わりに使用してください。まだ完了していない場合は、Bean を作成します。

FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);

はマネージド"bean"Bean 名で、Bean.classは適切なバッキング Bean クラスです。

必要に応じて、これをヘルパー メソッドにまとめて、キャストが不要になるようにすることができます (JSF ボーイはジェネリックと のClassパラメーターを利用しませんでしたevaluateExpressionGet)。

public static <T> T findBean(String managedBeanName, Class<T> beanClass) {
    FacesContext context = FacesContext.getCurrentInstance();
    return beanClass.cast(context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", beanClass));
}

次のように使用できます。

Bean bean = findBean("bean", Bean.class);

または、タイプなしで、@SuppressWarnings:

@SuppressWarnings("unchecked")
public static <T> T findBean(String managedBeanName) {
    FacesContext context = FacesContext.getCurrentInstance();
    return (T) context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", Object.class);
}

次のように使用できます。

Bean bean = findBean("bean");

更新:上記はJSF 1.2固有のものです。JSF 1.1 以前の場合、現在非推奨 Application#createValueBinding()の を使用する方法は次のとおりです。

FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().createValueBinding("#{bean}").getValue(context);
于 2010-01-12T16:11:07.750 に答える
3

このソリューションはどうですか:

public static Object getBean(String beanName)
{          
    Object returnObject = FacesContext.getCurrentInstance().getELContext().getELResolver().getValue(FacesContext.getCurrentInstance().getELContext(), null, beanName);  
    if (returnObject == null)  
        System.out.println("Bean with name " + beanName + " was not found. Check the faces-config.xml file if the given bean name is ok.");          
    return returnObject;
}

このようにして、Bean.class パラメーターを回避することもできます。

于 2011-05-07T00:03:08.970 に答える
0

質問: 使用します

FacesContext context = FacesContext.getCurrentInstance();

Bean bean = (Bean) context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);

コードがこれらのステートメントを実行するたびに、新しい Bean がインスタンス化されるようにしますか? それとも、最初に作成された同じインスタンスを参照するだけですか?

于 2010-12-06T22:41:22.093 に答える
0

1 つのメカニズムは、次のように、別の Bean に参照する Bean に Bean を注入することですexpensiveBean

  <managed-bean>
    <managed-bean-name>requestBean</managed-bean-name>
    <managed-bean-class>lifetime.RequestBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
      <property-name>cachedAsset</property-name>
      <property-class>lifetime.ExpensiveBean</property-class>
      <value>#{expensiveBean}</value>
    </managed-property>
  </managed-bean>

これはあまり「怠惰」ではありませんが、便利な場合があります。

于 2010-01-12T16:13:47.957 に答える