SpringMVC
WebFlux
Reactive Programming
Java
Spring Framework

Can I use SpringMvc and webflux together?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Yes, but you need to be precise about what "together" means. Spring MVC and Spring WebFlux are both part of the Spring ecosystem, yet they use different server-side programming models. In a typical Spring Boot application, adding both starters does not give you two equal web stacks running side by side.

What Actually Happens in Spring Boot

Spring MVC is the servlet-based stack. WebFlux is the reactive stack. If both spring-boot-starter-web and spring-boot-starter-webflux are on the classpath, Spring Boot normally chooses the servlet application type, which means MVC wins as the server runtime.

That default surprises people. They expect Boot to route some controllers through MVC and others through WebFlux. That is not the normal model. In one Boot application, you usually choose one server stack.

So the short answer is:

  • yes, both libraries can be on the classpath
  • no, that does not mean you are running both server runtimes in parallel by default

A Safe and Common Combination

One common pattern is an MVC application that uses WebClient from the WebFlux module as an HTTP client. That is completely reasonable and often useful.

java
1import org.springframework.context.annotation.Bean;
2import org.springframework.context.annotation.Configuration;
3import org.springframework.stereotype.Service;
4import org.springframework.web.bind.annotation.GetMapping;
5import org.springframework.web.bind.annotation.RestController;
6import org.springframework.web.reactive.function.client.WebClient;
7
8@Configuration
9class ClientConfig {
10    @Bean
11    WebClient webClient() {
12        return WebClient.builder()
13                .baseUrl("https://httpbin.org")
14                .build();
15    }
16}
17
18@Service
19class IpService {
20    private final WebClient webClient;
21
22    IpService(WebClient webClient) {
23        this.webClient = webClient;
24    }
25
26    String fetchIp() {
27        return webClient.get()
28                .uri("/ip")
29                .retrieve()
30                .bodyToMono(String.class)
31                .block();
32    }
33}
34
35@RestController
36class IpController {
37    private final IpService ipService;
38
39    IpController(IpService ipService) {
40        this.ipService = ipService;
41    }
42
43    @GetMapping("/ip")
44    String ip() {
45        return ipService.fetchIp();
46    }
47}

This app is still an MVC app. It just happens to use a reactive client library.

When You Should Choose WebFlux Instead

If your goal is a reactive server application with non-blocking request handling, then build the app as WebFlux from the start. That usually means using only the WebFlux starter, reactive data access, and avoiding blocking calls on the request path.

You can also force the application type explicitly:

java
1import org.springframework.boot.SpringApplication;
2import org.springframework.boot.WebApplicationType;
3import org.springframework.boot.autoconfigure.SpringBootApplication;
4
5@SpringBootApplication
6public class DemoApplication {
7    public static void main(String[] args) {
8        SpringApplication app = new SpringApplication(DemoApplication.class);
9        app.setWebApplicationType(WebApplicationType.REACTIVE);
10        app.run(args);
11    }
12}

That makes your intention explicit, which is valuable when dependency sets become messy.

Migration Strategy

If you have an existing MVC application and want to adopt reactive programming gradually, start small. Introduce WebClient first. Then isolate genuinely reactive flows, such as streaming or high-concurrency I/O, into services that can be made end to end non-blocking.

What you do not want is a half-reactive architecture where request handlers return reactive types but immediately call blocking JPA repositories or .block() deep in the stack. That adds complexity without gaining the scalability benefits of WebFlux.

In many teams, the cleanest migration path is one of these:

  1. keep the current app on MVC and use reactive clients where helpful
  2. build a separate WebFlux service for workloads that truly benefit from non-blocking I/O
  3. migrate the whole app to WebFlux only if the surrounding libraries are also reactive

Common Pitfalls

The most common mistake is adding both starters and assuming Boot will mix MVC controllers and WebFlux handlers automatically. Boot picks one application type for the server.

Another mistake is using WebFlux on top of blocking persistence, blocking SDK calls, or heavy synchronous business logic. That usually hurts clarity more than it helps throughput.

Developers also sometimes keep both stacks during migration for too long. If the app is fundamentally servlet-based, call it MVC and keep the design simple until you have a strong reason to switch.

Summary

  • Spring MVC and WebFlux can coexist as libraries, but one Boot app usually runs one server stack.
  • If both starters are present, Spring Boot normally chooses MVC as the server runtime.
  • Using WebClient inside an MVC app is a common and valid combination.
  • Choose WebFlux only when you can keep the request path meaningfully non-blocking.
  • For most migrations, prefer a deliberate architecture over trying to blend both server models implicitly.

Course illustration
Course illustration

All Rights Reserved.