Lesson 12. Quarkus vs. Spring Boot

1. Dependency Injection (CDI in Quarkus vs. Spring Boot)

Quarkus (Jakarta CDI)

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class GreetingService {
    public String greet(String name) {
        return "Hello, " + name;
    }
}

Spring Boot (@Service)

import org.springframework.stereotype.Service;

@Service
public class GreetingService {
    public String greet(String name) {
        return "Hello, " + name;
    }
}

2. REST API (JAX-RS in Quarkus vs. Spring Boot)

Quarkus (JAX-RS)

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class HelloResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello, Quarkus!";
    }
}

Spring Boot (@RestController)

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/hello")
public class HelloController {

    @GetMapping
    public String hello() {
        return "Hello, Spring Boot!";
    }
}

3. Configuration (MicroProfile Config in Quarkus vs. Spring Boot)

Quarkus (application.properties)

greeting.message=Hello from Quarkus!

Inject into a class:

import org.eclipse.microprofile.config.inject.ConfigProperty;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class GreetingConfig {

    @ConfigProperty(name = "greeting.message")
    String message;

    public String getMessage() {
        return message;
    }
}

Spring Boot (application.yml)

greeting:
  message: "Hello from Spring Boot!"

Inject using @Value:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class GreetingConfig {

    @Value("${greeting.message}")
    private String message;

    public String getMessage() {
        return message;
    }
}

4. ORM with Hibernate (Panache in Quarkus vs. Spring Boot)

Quarkus (Hibernate ORM with Panache)

import io.quarkus.hibernate.orm.panache.PanacheEntity;
import jakarta.persistence.Entity;

@Entity
public class Person extends PanacheEntity {
    public String name;
}

Spring Boot (Spring Data JPA)

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

Spring Boot Repository:

import org.springframework.data.jpa.repository.JpaRepository;

public interface PersonRepository extends JpaRepository<Person, Long> {
}

5. Lightweight Dependency Injection (Arc in Quarkus vs. Spring Boot)

Quarkus (Arc - Lightweight CDI Alternative)

import io.quarkus.arc.DefaultBean;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
@DefaultBean
public class MyBean {
    public String sayHello() {
        return "Hello from Arc!";
    }
}

Spring Boot (@Component)

import org.springframework.stereotype.Component;

@Component
public class MyBean {
    public String sayHello() {
        return "Hello from Spring Boot!";
    }
}

6. Reactive API (Mutiny in Quarkus vs. Spring WebFlux in Spring Boot)

Quarkus (Mutiny - Reactive API)

import io.smallrye.mutiny.Uni;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Path("/reactive")
public class ReactiveResource {

    @GET
    public Uni<String> sayHello() {
        return Uni.createFrom().item("Hello, Reactive Quarkus!");
    }
}

Spring Boot (Spring WebFlux)

import reactor.core.publisher.Mono;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/reactive")
public class ReactiveController {

    @GetMapping
    public Mono<String> sayHello() {
        return Mono.just("Hello, Reactive Spring Boot!");
    }
}

7. Native Compilation for Fast Startup (GraalVM in Quarkus vs. Spring Native in Spring Boot)

Quarkus (GraalVM Native Build)

./mvnw package -Dnative

Spring Boot (Spring Native)

./mvnw package -Pnative -DskipTests

Final Comparison Table

FeatureQuarkusSpring Boot
DI FrameworkJakarta CDI (Arc)Spring IoC (@Service, @Component)
REST APIJAX-RS (@Path, @GET)Spring MVC (@RestController, @GetMapping)
ConfigurationMicroProfile Config (@ConfigProperty)Spring Boot Config (@Value)
Database ORMHibernate ORM + PanacheSpring Data JPA (JpaRepository)
Lightweight DIArc (@DefaultBean)Spring (@Component)
Reactive ProgrammingMutiny (Uni, Multi)Project Reactor (Mono, Flux)
Native CompilationGraalVM optimizedSpring Native (experimental)

🚀 Quarkus is best for microservices, GraalVM, cloud-native applications
🔥 Spring Boot is best for enterprise, traditional full-stack apps