Spring Boot Integration

This section documents the current Vaadin release line — Vaadin 24 LTS / 25.x, Java 17+, Spring Boot 3 / Jakarta EE 10 — as published at the official Vaadin documentation, which is the reference these pages are written and verified against. No specific patch version is pinned. Flow (server-side Java) is the authoring style used throughout, with Hilla / React shown where it differs; Vaadin 7 and the pre-Flow architecture appear only as migration contrast.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, since Vaadin ships major releases roughly twice a year and its ecosystem iterates.

This section’s bibliography lists the reference material consulted while preparing these pages.

Spring Boot is the default backend for a Vaadin application: the starter auto-configures the Vaadin servlet, makes views injectable, and adds Vaadin-aware bean scopes. This page follows the Spring integration guide. For SQL itself, see the SQL Reference.

The starter

vaadin-spring-boot-starter (pulled in by every generated project) registers the VaadinServlet, scans your packages for @Route views, and enables the scopes below:

<dependency>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>

Limit the route scan for faster startup:

vaadin.allowed-packages=com.example.views,com.example.security

Beans and injection

Any @Component can be injected into a view through its constructor — Flow instantiates views through the Spring context. @SpringComponent is a thin alias that also plays nicely with the Vaadin scopes:

@Route("customers")
public class CustomerListView extends VerticalLayout {

    public CustomerListView(CustomerService service) {   // injected
        Grid<Customer> grid = new Grid<>(Customer.class);
        grid.setItems(service.findAll());
        add(grid);
    }
}

Vaadin bean scopes

Beyond singleton and prototype, the starter adds scopes tied to the Vaadin runtime:

Scope One instance per…

@VaadinSessionScope

user session (all that user’s tabs share it)

@UIScope

UI — i.e. per browser tab / window

@RouteScope + @RouteScopeOwner(View.class)

active route target; discarded on navigation away

@SpringComponent
@UIScope
public class ShoppingCart {          // one cart per tab
    private final List<LineItem> items = new ArrayList<>();
    // ...
}

A CRUD over Spring Data JPA

@Entity
public class Customer {
    @Id @GeneratedValue Long id;
    String name;
    String email;
    // getters / setters
}

public interface CustomerRepository extends JpaRepository<Customer, Long> { }

@Service
public class CustomerService {
    private final CustomerRepository repo;
    public CustomerService(CustomerRepository repo) { this.repo = repo; }

    public List<Customer> findAll() { return repo.findAll(); }
    @Transactional public Customer save(Customer c) { return repo.save(c); }
    @Transactional public void delete(Customer c) { repo.delete(c); }
}

@Route("customers")
public class CustomerCrudView extends VerticalLayout {

    private final Grid<Customer> grid = new Grid<>(Customer.class);
    private final Binder<Customer> binder = new Binder<>(Customer.class);
    private final CustomerService service;

    public CustomerCrudView(CustomerService service) {
        this.service = service;
        grid.setItems(service.findAll());
        grid.asSingleSelect().addValueChangeListener(e -> edit(e.getValue()));

        TextField name = new TextField("Name");
        binder.bindInstanceFields(this);
        Button save = new Button("Save", e -> {
            service.save(binder.getBean());
            grid.setItems(service.findAll());
        });
        add(grid, name, save);
    }

    private void edit(Customer c) {
        binder.setBean(c != null ? c : new Customer());
    }
}

For lazy loading and the transaction boundary, see Data Persistence.

application.properties

Common Vaadin keys (the full list is on Configuration and Dev Tools):

vaadin.launch-browser=true
vaadin.frontend.hotdeploy=true
vaadin.pnpm.enable=true
vaadin.productionMode=false

Spring events

Inject ApplicationEventPublisher to fire domain events; a @EventListener bean (or another view via a shared service) reacts. Combined with server push (Server Push) this notifies other users' open UIs.

Spring MVC and non-Boot Spring

Vaadin routes and Spring @RestController / @Controller mappings coexist under different URL paths in the same application — see REST and Services. In a plain Spring (non-Boot) WebApplication, add @EnableVaadin("com.example") to a @Configuration class instead of relying on the starter’s auto-configuration.

See also