47

マネージド Bean がコントローラーのように機能することは理解しています。なぜなら、あなたの唯一のタスクはビュー レイヤーをモデルに「リンク」することだからです。

Bean をマネージド Bean として使用するには、@ManagedBeanアノテーションを宣言する必要があります。これにより、JSF と Bean を直接やり取りできます。

この managedBean に (Spring から) コンポーネントを注入したい場合、2 つの方法があります。

  1. ManagedBean (「BasicDAO dao」など) でプロパティを選択し、プロパティの@ManagedProperty(#{"basicDAO"})上で宣言します。やっていると、"basicDAO"ManagedBean に Spring から Bean を注入しています。

  2. ManagedBean クラスで @Controller を宣言する@ManagedBeanと、 と@Controllerアノテーションがすべて一緒になります。プロパティでは、Spring から"BasicDAO dao"使用する必要があります。@Autowired

私の理解は正しいですか?

4

4 に答える 4

97

@ManagedBean@Controller

まず、Bean を管理するフレームワークを1 つ選択する必要があります。Bean を管理するには、JSF または Spring (または CDI) のいずれかを選択する必要があります。以下は機能しますが、根本的に間違っています。

@ManagedBean // JSF-managed.
@Controller // Spring-managed.
public class BadBean {}

まったく同じマネージド Bean クラスの2 つの完全に別個のインスタンスが作成されます。1 つは JSF によって管理され、もう 1 つは Spring によって管理されます。として参照する場合、実際に EL で使用されるものは明確ではありません#{someBean}SpringBeanFacesELResolverに登録している場合faces-config.xmlは、JSF 管理のものではなく、Spring 管理のものになります。それがない場合は、JSF 管理のものになります。

@RequestScopedまた、 、@ViewScoped@SessionScopedまたは@ApplicationScopedfrom packageなどの JSF マネージド Bean 固有のスコープを宣言すると、javax.faces.*によってのみ認識および使用され@ManagedBeanます。@Controller独自の@Scope注釈が必要なため、理解されません。存在しない場合、これはデフォルトでシングルトン (アプリケーション スコープ) になります。

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
@Controller // Spring-managed (without own scope, so actually becomes a singleton).
public class BadBean {}

を介して上記の Bean を参照する#{someBean}と、JSF 管理のビュー スコープ Bean ではなく、Spring 管理のアプリケーション スコープ Bean が返されます。


@ManagedProperty@Autowired

JSF 固有@ManagedPropertyは、JSF 管理の Bean でのみ機能します。つまり、 を使用している場合です@ManagedBean。Spring 固有の@Autowiredは、Spring 管理の Bean でのみ機能します。つまり、 を使用している場合です@Controller。以下のアプローチは、多かれ少なかれ同等であり、混在させることはできません。

@ManagedBean // JSF-managed.
@RequestScoped // JSF-managed scope.
public class GoodBean {

    @ManagedProperty("#{springBeanName}")
    private SpringBeanClass springBeanName; // Setter required.
}
@Component // Spring-managed.
@Scope("request") // Spring-managed scope.
public class GoodBean {

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.
}

javadocに従ってSpringBeanFacesELResolver登録した場合は、faces-config.xml

<application>
    ...
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

したがって、Spring マネージド Bean を 経由で EL で#{springBeanName}参照できます@ManagedProperty。基本的には、指定された EL 式の評価結果を設定するため、それらを参照することもできます。逆に、 を介して JSF マネージド Bean を注入すること@Autowiredは、まったくサポートされていません。ただし@Autowired、Bean を から拡張する場合は、JSF マネージド Bean で を使用できますSpringBeanAutowiringSupport。これにより、コンストラクターの呼び出し中に JSF マネージド Bean インスタンスが Spring の autowirable コンテキストに自動的に登録されます。つまり、すべて@Autowiredが 以降で使用可能になります@PostConstruct

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean extends SpringBeanAutowiringSupport implements Serializable {

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.

    @PostConstruct
    private void init() {
        // springBeanName is now available.
    }
}

または、アーキテクチャが別の基本クラスからの Bean の拡張を許可しない場合は、以下のように、いつでも JSF マネージド Bean インスタンスを Spring autowirable コンテキストに手動で登録できます。トリックについては、JSF 2 と Spring 3 (または Spring 4) を適切に統合する方法も参照してください。

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean implements Serializable {

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.

    @PostConstruct
    private void init() {
        FacesContextUtils
            .getRequiredWebApplicationContext(FacesContext.getCurrentInstance())
            .getAutowireCapableBeanFactory().autowireBean(this);

        // springBeanName is now available.
    }
}

@XxxScoped@Scope

Spring@Scopeでは、JSF スコープのサポートが制限されています。JSF の に相当するものはありません@ViewScoped。基本的には、独自のスコープを自作するか、上記のように Spring autowirable コンテキストで JSF マネージド Bean インスタンスを手動で登録することに固執します。

@FlowScoped一方、Spring WebFlow は、新しいアノテーションを介して JSF 2.2 に引き継がれました。したがって、すでに JSF 2.2 を使用している場合、フロー スコープのみが必要な場合は、必ずしも Spring WebFlow を使用する必要はありません。


CDI - すべてを統一しようとしています

Java EE 6 以降、CDI は Spring DI の標準的な代替手段として提供されています。これにはそれぞれ@Namedと の@Inject注釈があり、独自のスコープ セットもあります。Spring を使用していないため、Spring とどのように相互作用するかはわかりませんが、@Inject内で動作し@ManagedBean@ManagedProperty内でBean@ManagedBeanを参照できます。@Named一方、Bean@ManagedProperty内では機能しません。@Named

CDI の目的は、すべての異なる Bean 管理フレームワークを 1 つの仕様/インターフェースに統合することです。Spring は完全な CDI 実装であった可能性がありますが、部分的にのみ実装することを選択しました (JSR-330 のみjavax.inject.*がサポートされ、JSR-299 はサポートされてjavax.enterprise.context.*いません)。Spring は CDI をサポートしますか?も参照してください。そしてこのチュートリアル

@ManagedBeanJSF は、将来のバージョンで Bean 管理と非推奨およびフレンドのために CDI に移行する予定です。

@Named // CDI-managed.
@ViewScoped // CDI-managed scope.
public class BetterBean implements Serializable {

    @Inject
    private SpringBeanClass springBeanName; // No setter required.

    @PostConstruct
    private void init() {
        // springBeanName is now available.
    }
}

以下も参照してください。

于 2013-08-22T18:34:17.057 に答える
1

これを行う簡単な方法は、XML を使用することです。@Componentすでに作成されている jsf マネージド Bean で使用しまし@Autowiredたが、faces-config.xml にマネージド Bean が既に存在していたため、機能しませんでした。そのマネージド Bean 定義をそのマネージド プロパティとともに xml ファイルに保持することが必須である場合は、Spring Bean を別のマネージド プロパティとしてマネージド Bean タグ内に追加することをお勧めします。ここで、Spring Bean は spring-config.xml で定義されています (代わりにどこかで自動配線できます)。https://stackoverflow.com/a/19904591/5620851を参照 してください

私が編集しました。注釈 @Managed と @Component を介して完全に実装するか、両方の xml を介して実装することをお勧めします。

于 2016-10-14T09:04:15.400 に答える