2016-09-30 4 views
1

私はこれを本当に奇妙で不安な問題にしています。低性能のコンピュータでは、Spring Contextの初期化中にシングルトンBeanの一部が複製されます。これは、パフォーマンスの低いハードウェアを搭載したコンピュータでのみ発生し、一貫して発生します。パフォーマンスの低いコンピュータでのスプリングビーンシングルトンの複製

これまで私が知ることは、循環依存関係にある一連のクラスに起こっているようであり、Bean initメソッドとは関係があると思われます。循環依存関係は、コンストラクタではなくinitメソッドを介してLockControlをMainContentPaneに注入することで解決されます。

私は2つのログを持っています.1つは通常のパフォーマンスコンピュータから、もう1つは低パフォーマンスコンピュータからです。ログには違いと問題点が表示されます。行末の数字は、System.identityHashCode(object)メソッドのインスタンスIDです。ログ形式は次のとおりです。

LOGLEVEL [Thread ID] LoggingClass Message 

通常のパフォーマンスコンピュータでは、次のような出力が発生します。

INFO [JavaFX Application Thread] MainContentPane  Constructor: 869589588 
INFO [JavaFX Application Thread] MainContentPane  Getting LockScreen In Spring Init.... 

INFO [JavaFX Application Thread] SessionHandler  Constructor: 939274676 
INFO [JavaFX Application Thread] SessionHandler  Injected MainContentPane Instance: 869589588 
INFO [JavaFX Application Thread] UserStateBinder  Constructor: 2010765576 
INFO [JavaFX Application Thread] UserStateBinder  Injected SessionHandler Instance: 939274676 
INFO [JavaFX Application Thread] LockScreenLockedController Constructor: 1866179042 
INFO [JavaFX Application Thread] LockScreenLockedController Injected UserStateBinder Instance: 2010765576 
INFO [JavaFX Application Thread] LockScreen   Constructor: 204176749 
INFO [JavaFX Application Thread] LockScreen   Injected LockScreenLockedController Instance: 1866179042 
INFO [JavaFX Application Thread] LockScreen   This instance: 204176749 
INFO [JavaFX Application Thread] LockScreen   Bean Factory instance: 1371189401 
INFO [JavaFX Application Thread] MainContentPane  Injected LockScreen Instance: 204176749 

ここに重複はありません。

しかし、パフォーマンスの低いコンピュータからログを見ると、上記のような初期化の後に重複が作成されていることがわかります。

INFO [JavaFX Application Thread] MainContentPane  Constructor: 22324067 
INFO [JavaFX Application Thread] MainContentPane  Getting LockScreen In Spring Init.... 

INFO [JavaFX Application Thread] SessionHandler  Constructor: 32463502 
INFO [JavaFX Application Thread] SessionHandler  Injected MainContentPane Instance: 22324067 
INFO [JavaFX Application Thread] UserStateBinder  Constructor: 19793387 
INFO [JavaFX Application Thread] UserStateBinder  Injected SessionHandler Instance: 32463502 
INFO [JavaFX Application Thread] LockScreenLockedController Constructor: 29065840 
INFO [JavaFX Application Thread] LockScreenLockedController Injected UserStateBinder Instance: 19793387 
INFO [JavaFX Application Thread] LockScreen   Constructor: 12729388 
INFO [JavaFX Application Thread] LockScreen   Injected LockScreenLockedController Instance: 29065840 
INFO [JavaFX Application Thread] LockScreen   This instance: 12729388 
INFO [JavaFX Application Thread] LockScreen   Bean Factory instance: 30716643 
INFO [JavaFX Application Thread] MainContentPane  Injected LockScreen Instance: 12729388 

INFO [JavaFX Application Thread] SessionHandler  Constructor: 11043228 
INFO [JavaFX Application Thread] SessionHandler  Injected MainContentPane Instance: 22324067 
INFO [JavaFX Application Thread] UserStateBinder  Constructor: 24902967 
INFO [JavaFX Application Thread] UserStateBinder  Injected SessionHandler Instance: 32463502 
INFO [JavaFX Application Thread] LockScreenLockedController Constructor: 17521714 
INFO [JavaFX Application Thread] LockScreenLockedController Injected UserStateBinder Instance: 19793387 
INFO [JavaFX Application Thread] LockScreen   Constructor: 16791356 
INFO [JavaFX Application Thread] LockScreen   Injected LockScreenLockedController Instance: 29065840 
INFO [JavaFX Application Thread] LockScreen   This instance: 16791356 
INFO [JavaFX Application Thread] LockScreen   Bean Factory instance: 30716643 

ここで、MainContentPaneクラスを除くすべてのクラスで作成された2番目のインスタンスセットがあることがわかります。新しいクラスのセットは、以前のインスタンスのセット(IDのチェック)に依存性が注入され、Beanファクトリは以前と同じインスタンスになります。

これらのメッセージはすべてメインスレッド(JavaFXアプリケーションスレッド)に表示されるため、並行性の問題もないようです。

プロジェクトには、埋め込みJetty HTTPサーバーも含まれています。パフォーマンスの低いコンピュータでこの問題が発生する可能性のあるものがJettyに存在するかどうかはわかりません。

バージョン:

JRE(incl. JavaFX): 1.8.0.101 
Spring: 4.3.3.RELEASE 
Jetty + Websocket: 9.3.6.v20151106 

私はこの問題はsetAllowBeanDefinitionOverriding(偽)を設定するSpringコンテキストを設定することで解決されていることが疑われます。しかし、それはどちらも役に立たなかった。

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 
     context.setAllowBeanDefinitionOverriding(false); 
     context.register(ClientContext.class, 
       MainContext.class, 
       CommonContext.class, 
       CciContext.class, 
       PersistenceContext.class, 
       SimulatorContext.class); 
     context.refresh(); 

必要な追加情報がある場合は教えてください。いつでも助けてくれてありがとうございます。

編集:私は今、すべてのinitilizationとすべてのBeanへのアクセスは、単一のスレッドから起こっていることを確認しました

。 トレースログには2つの興味深い事実しか見つかりませんでした。 最初は、まったく同じソフトウェアバージョン(パラレルでSpringを初期化していますか?)であっても、すべての初期化が同じ順序で行われるようです。 第2に、中規模のパフォーマンスコンピュータに重複があります。彼らはUserStateBinderクラスに重複(または再初期化?)しかありません。高性能な開発用コンピュータには、この問題はまったくありません。

この問題の解決策が見つからないため、明日から私たちのプロジェクトから春が削除されるでしょう。他の誰かが私に理論をテストしてもらいたいなら、私はまだプロジェクトの最新版を入手できます。

+0

したがって、 'MainContentPane'に' LockScreen'を設定すると、循環参照は発生しますか?それは各コンピュータ上の同じJVMバージョンですか? – Asoub

+0

循環参照は、 LockScreen - > LockScreenLockedController - > UserStateBinder - > SessionHandler - > MainContentPane - > LockScreenであり、MainContentPaneがそのコンストラクタの代わりにSpring initメソッドでLockScreen Beanを取得することによって解決されます。 JVMに関しては、はい、すべてのコンピュータで同じです。 JREはアプリケーションにバンドルされています。 – Flipbed

+0

それは本当にあいまいです。遅い遅いコンピュータでdebbugger(可能であれば食付)を試すことができますか? – Asoub

答えて

0

さらに多くのテストをしたところ、問題を解決できましたが、奇妙な動作の根本原因は見つかりませんでした。

私は、ビヘイビアを変更する何らかの種類の時間依存性を持つBeanを初期化するSpringによって何らかの原因で動作が疑われます。これが並列性の結果であるかどうかは私は確信できません。

問題は循環依存関係LockScreen - > LockScreenLockedController - > UserStateBinder - > SessionHandler - > MainContentPane - > LockScreenでのみ発生していました。 MainContentPaneのコンストラクタ依存関係をSpringのinitメソッドに移動することで、循環依存関係が解消されました。コードはこのように見えました。

解決策は、Springの依存関係を、このような@DependsOnアノテーションで明示的に宣言することでした。

@Bean(initMethod = "init") 
public MainContentPane mainContentPane() {...} 

@Bean 
@DependsOn("lockScreenLockedController") 
public LockScreen lockScreen() {...} 

@Bean 
@DependsOn("userStateBinder") 
public LockScreenLockedController lockScreenLockedController() {...} 

@Bean 
@DependsOn("sessionHandler") 
public UserStateBinder userStateBinder() {...} 

@Bean 
@DependsOn("mainContentPane") 
public SessionHandler sessionHandler() {...} 

私はこれが同じ問題を抱えている人を助けてくれることを願っています。なぜ、Springがコンピュータのパフォーマンスによってこのように振る舞うのかを知りたいのです。

関連する問題