2016-09-30 2 views
1

그래서 저는 정말 이상하고 불안한 문제가 있습니다. 성능이 낮은 컴퓨터에서는 싱글 톤 빈의 일부가 스프링 컨텍스트 초기화 중에 복제됩니다. 이는 성능이 낮은 하드웨어가있는 컴퓨터에서만 발생하며 일관되게 발생합니다.저 성능 컴퓨터에서의 스프링 빈 싱글 톤 복제

지금까지 말할 수있는 것은 원형 종속성을 가진 많은 클래스에서 발생하는 것으로 보이며 bean init 메소드와 관련이 있다고 생각됩니다. 원형 종속성은 생성자 대신 init 메소드를 통해 LockControl을 MainContentPane에 주입하여 해결됩니다.

두 개의 로그가 있습니다. 하나는 정상 성능 컴퓨터이고 다른 하나는 저 성능 컴퓨터입니다. 로그에 차이점과 문제점이 표시됩니다. 줄 끝의 숫자는 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 클래스를 제외한 모든 클래스의 생성 된 인스턴스의 두 번째 세트가 있음을 알 수있다. 새로운 클래스 집합은 이전 인스턴스 집합과의 종속성 주입 (id 확인)이며 bean factory는 이전과 같은 인스턴스입니다.

이러한 모든 메시지는 주 스레드 (JavaFX 응용 프로그램 스레드)에 인쇄되므로 동시성 문제가없는 것으로 보입니다.

프로젝트에는 임베디드 Jetty http 서버가 포함되어 있습니다. 성능이 낮은 컴퓨터에서이 문제를 일으킬 수있는 것이 Jetty에 있는지 여부를 알 수 없습니다.

버전 :

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

나는이 문제가 (false)를 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(); 

추가 정보가 필요하면 알려주세요. 언제든지 도와 주셔서 감사합니다.

편집 : 나는 이제 모든시 초기화하고 모든 빈 액세스는 단일 스레드에서 일어나고 있음을 확인했다

. 추적 로그에서 두 가지 흥미로운 사실을 발견 할 수있었습니다. 첫 번째로, 모든 초기화 작업은 완전히 동일한 소프트웨어 버전 (팔레 엘에서 초기화되는 스프링입니까?) 인 경우에도 동일한 순서로 발생합니다. 둘째, 중간 성능 컴퓨터에는 중복이 있습니다! 그것들은 UserStateBinder 클래스에 중복 (또는 아마 재 초기화)만을 가지고 있습니다. 고성능 개발 컴퓨터에는이 문제가 전혀 없습니다.

우리는이 문제에 대한 해결책을 찾지 못해 내일부터 우리 프로젝트에서 봄을 제거 할 것입니다. 다른 누구라도 이론을 시험해보기를 원한다면 나는 현재 프로젝트의 현재 버전을 사용할 수 있습니다.

+0

그래서, 'MainContentPane'에'LockScreen'을 설정할 때 순환 빈 참조가 발생합니까? 각 컴퓨터의 동일한 JVM 버전입니까? – Asoub

+0

순환 참조는 LockScreen -> LockScreenLockedController -> UserStateBinder -> SessionHandler -> MainContentPane -> LockScreen이며, MainContentPane이 생성자 대신 Spring init 메소드에서 LockScreen 빈을 가져 오면 해결됩니다. JVM에 대해서는 모든 컴퓨터에서 동일합니다. JRE는 애플리케이션과 함께 번들로 제공됩니다. – Flipbed

+0

그건 정말 모호한 소리입니다. 천천히 느린 컴퓨터에서 debbugger (가능한 경우 일식 포함)를 사용해 볼 수 있습니까? – Asoub

답변

0

많은 추가 테스트를 마친 후 문제를 해결할 수 있었지만 이상한 행동의 근본 원인을 찾을 수 없었습니다.

나는 동작이 어떻게 든 행동을 변경하는 일종의 시간 의존성을 가진 빈을 초기화함으로써 발생한다고 생각한다. 이것이 병렬 처리의 결과인지 아닌지에 대해서는 분명히 말할 수 없습니다.

이 문제는 순환 종속성 LockScreen -> LockScreenLockedController -> UserStateBinder -> SessionHandler -> MainContentPane -> LockScreen에서만 발생했습니다. MainContentPane의 생성자 종속성을 Spring init 메소드로 이동하면 순환 종속성이 손상됩니다. 코드는 다음과 같이 보입니다.

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

@Bean 
public LockScreen lockScreen() {...} 

@Bean 
public LockScreenLockedController lockScreenLockedController() {...} 

@Bean 
public UserStateBinder userStateBinder() {...} 

@Bean 
public SessionHandler sessionHandler() {...} 

해결 방법은 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() {...} 

나는이 같은 문제를 가지고 사람을 도움이되기를 바랍니다 그리고 난 아직도 정말 봄이 컴퓨터의 성능에 따라이 방식으로 작동 이유를 알고 싶습니다.

관련 문제