그래서 저는 정말 이상하고 불안한 문제가 있습니다. 성능이 낮은 컴퓨터에서는 싱글 톤 빈의 일부가 스프링 컨텍스트 초기화 중에 복제됩니다. 이는 성능이 낮은 하드웨어가있는 컴퓨터에서만 발생하며 일관되게 발생합니다.저 성능 컴퓨터에서의 스프링 빈 싱글 톤 복제
지금까지 말할 수있는 것은 원형 종속성을 가진 많은 클래스에서 발생하는 것으로 보이며 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 클래스에 중복 (또는 아마 재 초기화)만을 가지고 있습니다. 고성능 개발 컴퓨터에는이 문제가 전혀 없습니다.
우리는이 문제에 대한 해결책을 찾지 못해 내일부터 우리 프로젝트에서 봄을 제거 할 것입니다. 다른 누구라도 이론을 시험해보기를 원한다면 나는 현재 프로젝트의 현재 버전을 사용할 수 있습니다.
그래서, 'MainContentPane'에'LockScreen'을 설정할 때 순환 빈 참조가 발생합니까? 각 컴퓨터의 동일한 JVM 버전입니까? – Asoub
순환 참조는 LockScreen -> LockScreenLockedController -> UserStateBinder -> SessionHandler -> MainContentPane -> LockScreen이며, MainContentPane이 생성자 대신 Spring init 메소드에서 LockScreen 빈을 가져 오면 해결됩니다. JVM에 대해서는 모든 컴퓨터에서 동일합니다. JRE는 애플리케이션과 함께 번들로 제공됩니다. – Flipbed
그건 정말 모호한 소리입니다. 천천히 느린 컴퓨터에서 debbugger (가능한 경우 일식 포함)를 사용해 볼 수 있습니까? – Asoub