私は、Spring を使用して次のように依存性注入を行うことに慣れています。
<context:component-scan base-package="org.emmerich.myapp" />
次に、依存クラスに次Autowired
のように注釈を付けます。
public class DependentClass {
@Autowired
private Dependency dependency;
}
ただし、Hibernate 4.0 での変更により、Integrator
サービス検出に新しいインターフェイスを使用することをお勧めします。postUpdate
これには、postDelete
などのトリガーのイベント リスナーの追加が含まれます。
残念ながら、これは注釈付きの依存関係による依存関係の注入ではうまく機能しません。私は次の設定をしています:
リスナーを に追加するために定義したインテグレーターServiceFactory
。これはファイルで参照されますMETA-INF/services/org.hibernate.integrator.spi.Integrator
。
public class MyIntegrator implements Integrator {
private MyListener listener;
public MyIntegrator() {
listener = new MyListener();
}
@Override
public void integrate(Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
final EventListenerRegistry eventRegistry =
serviceRegistry.getService(EventListenerRegistry.class);
eventRegistry.prependListeners(EventType.POST_COMMIT_INSERT, listener);
}
MyListener
また、典型的なイベント リスナーのように見えるclass も定義しました。
@Component
public class MyListener implements PostInsertEventListener {
@Autowired
private Dependent dependent;
public void onPostInsert(PostInsertEvent event) {
// dependent == null
}
}
残念ながら、コメントで示されているように、これは機能しません。MyListener
内部でインスタンス化しているためだと思いますがMyIntegrator
、コンポーネントを取得せず、コンポーネントを自動配線しません。ただし、これを試してみると:
@Component
public class MyIntegrator {
@Autowired
private MyListener listener;
...
}
次に、リスナーは自動配線されません。
まず、Spring を使用してやらなければならないことが間違っていると感じますnew MyListener()
。それを自動配線された依存関係として定義し、Spring にシングルトンを作成してもらうことができると期待しています。私の質問はこれです:
新しい Integrator インターフェイスで依存性注入を使用する最善の方法は何ですか? インテグレーターは SessionFactory を構築するために使用されるため、インテグレーターが自分自身を統合するように求められたとき、利用可能なアプリケーション コンテキストがないと思います。そのため、インテグレーターで必要な Bean はすべて「昔ながらの」方法で作成する必要があり、自動配線を受け取りません。
私は春の世界にまったく慣れていませんが、これは私が見るべきものだと思いますか? SessionFactory にいるときはアプリケーションの別のスコープにいることは理解していますが、Bean への参照を取得して autowire を有効にする方法はありnew
ますか?
私が思いついた解決策は、ApplicationContextAware
. MyListener
これは、コンテキストが使用可能なときはいつでもへの参照を受け取ることを意味しApplicationContext
、Bean の構築ではなく、メソッド呼び出しでコンテキストから Bean を参照しました。Bean を作成してnew
もこれは制限されないため、Spring は引き続きアプリケーション コンテキストを提供します。
@Component
public class MyListener implements PostInsertEventListener, ApplicationContextAware {
private static ApplicationContext context;
public void onPostInsert(PostInsertEvent event) {
// getDependent() == correct!
}
public void setApplicationContext(ApplicationContext context) throws BeanException {
this.context = context;
}
public Dependent getDependent() {
return context.getBean(Dependent.class);
}
}
より良い方法はありますか?