JBoss 6 Final にデプロイされた大規模な Java EE 6 アプリケーションに取り組んでいます。私の現在のタスクには、@EJB の代わりに一貫して @Inject を使用することが含まれていますが、いくつかのタイプの Bean、特に @MessageDriven Bean と @Scheduled メソッドを使用した Bean でいくつかの問題に遭遇しています。
タイミング (@Schedule の場合) が不運な場合、または起動時に MDB のキューにメッセージがある場合、注入されたリソース (EJB 自体) がまだバインドされていないため、Bean のインスタンス化が失敗します。 .
@Inject を使用しているため、コンテナー自体は @Inject を気にしないため、EJB コンテナーは Bean の準備ができていると見なしていると推測します。おそらく、@EJB インジェクションがないため、Bean を使用する準備ができていると想定しているだけです。注入するリソースがまだ実際にはバインドされていないため、注入された CDI プロキシは失敗します。
小さな例:
@Stateless
@LocalBean
public class MySupportingBean {
public void doSomething() {
...
}
}
@Singleton
public class MyScheduledBean {
@Inject
private MySupportingBean supportingBean;
@Schedule(second = "*/1", hour = "*", minute = "*", persistent = false)
public void onTimeout() {
supportingBean.doSomething();
}
}
上記の例は、Bean が 2 つしかないため、頻繁に失敗することはありませんが、私が取り組んでいるプロジェクトでは多くの EJB がバインドされ、問題が増幅されます。ただし、MySupportingBean が最初にバインドされるという保証がないため、失敗する可能性があります。また、MySupportingBean がバインドされる前に onTimeout が呼び出されると、MyScheduledBean のインスタンス化が失敗します。代わりに @EJB を使用した場合、MyScheduledBean は、MySupportingBean への依存関係が満たされるまでバインドされません。
この例は onTimeout 自体では失敗しませんが、CDI が MySupportingBean を注入しようとしたときに失敗することに注意してください。
私はさまざまなフォーラムで、@Inject が常に優れていると多くの人が主張する多くの投稿を読みました。一般的には同意しますが、@Inject と組み合わせた @Schedule または @MessageDriven をどのように処理しますか? 私の経験では、そのような場合に Bean が機能するかどうかは運次第であり、EJB がデプロイされる順序と @Schedule または onMessage が呼び出されるタイミングに応じて、Bean は任意に失敗します。