Question: How should ViewModels and Services communicate in an MVVM-based JavaFX + Spring Boot application?
Context I'm building a JavaFX + Spring Boot application following the MVVM pattern. In my setup: Controllers delegate to ViewModels. ViewModels handle UI-bound logic. Services manage business logic. Problem I have: A SharedLoginViewModel that manages the overall login workflow. A TokenCreationViewModel responsible for creating a token during that workflow. But TokenCreationViewModel needs to trigger a workflow transition in SharedLoginViewModel. Injecting one into the other leads to a circular dependency. Minimal Example @Component public class SharedLoginViewModel { private final TokenCreationViewModel tokenCreationViewModel; // ❌ Circular @Autowired public SharedLoginViewModel(TokenCreationViewModel tokenCreationViewModel) { this.tokenCreationViewModel = tokenCreationViewModel; } public void advanceWorkflow() { System.out.println("Advancing workflow..."); } } @Component public class TokenCreationViewModel { private final SharedLoginViewModel sharedLoginViewModel; // ❌ Circular @Autowired public TokenCreationViewModel(SharedLoginViewModel sharedLoginViewModel) { this.sharedLoginViewModel = sharedLoginViewModel; } public void createToken() { sharedLoginViewModel.advanceWorkflow(); } } Error UnsatisfiedDependencyException: Error creating bean with name 'sharedLoginViewModel': Requested bean is currently in creation: Is there an unresolvable circular reference? What I've tried Direct reference (as above) — leads to circular dependency. Spring Events — works but feels overkill for small interactions. Custom Interface injection — considering this as a decoupling strategy. Goal Decouple TokenCreationViewModel from SharedLoginViewModel. Keep ViewModels modular and testable without tight coupling. Is there a recommended pattern (Observer, Mediator, Event, Interface) for cross-ViewModel communication in Spring + JavaFX using MVVM?

Context
I'm building a JavaFX + Spring Boot application following the MVVM pattern. In my setup:
Controllers delegate to ViewModels.
ViewModels handle UI-bound logic.
Services manage business logic.
Problem
I have:
A SharedLoginViewModel that manages the overall login workflow.
A TokenCreationViewModel responsible for creating a token during that workflow.
But TokenCreationViewModel needs to trigger a workflow transition in SharedLoginViewModel. Injecting one into the other leads to a circular dependency.
Minimal Example
@Component
public class SharedLoginViewModel {
private final TokenCreationViewModel tokenCreationViewModel; // ❌ Circular
@Autowired
public SharedLoginViewModel(TokenCreationViewModel tokenCreationViewModel) {
this.tokenCreationViewModel = tokenCreationViewModel;
}
public void advanceWorkflow() {
System.out.println("Advancing workflow...");
}
}
@Component
public class TokenCreationViewModel {
private final SharedLoginViewModel sharedLoginViewModel; // ❌ Circular
@Autowired
public TokenCreationViewModel(SharedLoginViewModel sharedLoginViewModel) {
this.sharedLoginViewModel = sharedLoginViewModel;
}
public void createToken() {
sharedLoginViewModel.advanceWorkflow();
}
}
Error
UnsatisfiedDependencyException: Error creating bean with name 'sharedLoginViewModel': Requested bean is currently in creation: Is there an unresolvable circular reference?
What I've tried
- Direct reference (as above) — leads to circular dependency.
- Spring Events — works but feels overkill for small interactions.
- Custom Interface injection — considering this as a decoupling strategy.
Goal
Decouple TokenCreationViewModel from SharedLoginViewModel.
Keep ViewModels modular and testable without tight coupling.
Is there a recommended pattern (Observer, Mediator, Event, Interface) for cross-ViewModel communication in Spring + JavaFX using MVVM?