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?

Apr 24, 2025 - 07:53
 0
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

  1. Direct reference (as above) — leads to circular dependency.
  2. Spring Events — works but feels overkill for small interactions.
  3. 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?