2015-01-09 20 views
6

基本的なユーザー情報データを読み込むため、Webアプリケーションの起動ごとに1回だけ実行されるアプリケーションリスナーがあります。アプリの起動時に最初の要求がサーバーに到着したとき:WebアプリケーションでSpring ApplicationListenerが2回起動される

public class DefaultUsersDataLoader implements ApplicationListener<ContextRefreshedEvent> { 
    @Override 
    @Transactional 
    public void onApplicationEvent(ContextRefreshedEvent e) {...} 
} 

どういうわけか、それが2回実行されます。なぜこれが起こっているのですか?どうすればそれを防ぐことができますか?

+0

ポストのweb.xmlを使用してリスナクラスのメソッドを注釈を付けないでください.... – Braj

+0

私は同じ問題を抱えていました。 @EventListenerを削除すると、問題が解決しました。誰か説明がありますか? –

答えて

11

通常、Spring MVCアプリケーションでは、ContextLoaderListenerDispatcherServletの両方があります。どちらのコンポーネントも独自のApplicationContextを作成し、両方ともContextRefreshedEventを起動します。

DispatcherServletは、ContextLoaderListenerを親として作成したApplicationContextを使用します。子コンテキストから起動されたイベントは、親コンテキストに伝播されます。

ApplicationListener<ContextRefreshedEvent>がルートコンテキスト(ContextLoaderListenerによってロードされたもの)で定義されている場合、イベントを2回受信します。

+5

ありがとうございます。私は 'e.getApplicationContext()。getParent()!= null'でそれを排除しましたが、ちょっとハッキリしているようです。周りにもっと良い練習があるのだろうか? –

+0

リスナーがすでに呼び出されていれば、ブール値を切り替えることはできません。いくつかのデータをロードするだけで、Spring 4.1を使用している場合は、['SmartInitializingSingleton'](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans /factory/SmartInitializingSingleton.html)代わりに。 –

+0

また、Webコンテキストがコントローラ以外のBeanをインスタンス化しないようにすることもできます。すなわち、コントローラおよび他のそのような豆の親である「ウェブ」パッケージのみを含むように、コンポーネントスキャンベースパッケージを強制する。これは、あなたのリスナーがルートコンテキストにのみ存在することを確実にしなければならないため、ルートコンテキストイベントのみを取得します。 – Steve

関連する問題