Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’re going to compare Micronaut and Spring Boot. Spring Boot is a part of the popular Spring framework used for getting Spring applications up and running quickly. Micronaut is a JVM-based framework created to address some of the weaknesses of Spring/Spring Boot.

We’ll compare the two frameworks in several areas. First, we’ll compare the ease of creating a new application, language support, and other configuration options. Then we’ll look at two simple REST applications. Finally, we’ll compare the code and measure performance differences.

2. Features

In the following sections, we’ll break down several features in the two frameworks.

2.1. Setup

First, we’ll compare the ease of getting a new application up and running in the two frameworks.

Both Micronaut and Spring Boot offer multiple convenient methods for creating new applications. For example, we can create a new application using either framework with a command-line interface. Alternatively, we could use the Spring Initializr for Spring Boot or a similar tool for Micronaut called Launch.

In terms of IDE support, we can use Spring Boot plugins for most popular IDEs, including its flavor of Eclipse, the Eclipse Spring Tools Suite. We have a Micronaut plugin available to us if we’re using IntelliJ.

2.2. Language Support

As we turn to language support, we’ll find that it’s nearly identical for Spring Boot and Micronaut. For both frameworks, we can choose between Java, Groovy, or Kotlin. If we choose Java, both frameworks support Java 8, 11, and 17. Additionally, we can use either Gradle or Maven with both frameworks.

2.3. Servlet Container

Using Spring Boot, our application will use Tomcat by default. However, we can configure Spring Boot to use either Jetty or Undertow as well.

Our Micronaut applications will, by default, run on a Netty-based HTTP Server. However, we can choose to switch our application to run on Tomcat, Jetty, or Undertow.

2.4. Properties Configuration

For Spring Boot, we can define our properties in application.properties or application.yml. We can use the application-{env}.properties convention to provide different properties for different environments. Additionally, we can override these applications file provided properties using system properties, environment variables, or JNDI attributes.

We can use application.properties, application.yml, and application.json for our properties files in Micronaut. We can also use the same convention for supplying environment-specific properties files. If we need to override any properties, we can use system properties or environment variables.

2.5. Messaging Support

If we’re using messaging with Spring Boot, we have Active MQ, Artemis, Rabbit MQ, and Apache Kafka available to us.

On the Micronaut side, we have Apache Kafka, Rabbit MQ, and Nats.io as options.

2.6. Security

Spring Boot offers five authorization strategies: basic, form login, JWT, SAML, and LDAP. If we’re using Micronaut, we have the same options minus the SAML.

Both frameworks provide us with OAuth2 support.

In terms of actually applying the security, both frameworks allow us to use annotations to secure methods.

2.7. Management and Monitoring

Both frameworks provide us with the ability to monitor various metrics and statistics in our applications. We can define custom endpoints in both frameworks. We also can configure endpoint security in both frameworks.

However, the Spring Boot actuator provides several more built-in endpoints than Micronaut.

2.8. Template Languages

We can create complete full-stack applications with both frameworks, using provided template languages to render the front-end.

For Spring Boot, our choices are Thymeleaf, Apache Freemarker, Mustache, and Groovy. We can also use JSP, although the practice is discouraged.

We have a few more options available in Micronaut: Thymeleaf, Handlebars, Apache Velocity, Apache Freemarker, Rocker, Soy/Closure, and Pebbles.

2.9. Cloud Support

Spring Boot applications rely on third-party libraries for many cloud-specific features.

Micronaut is natively designed for cloud microservices. Cloud concepts that Micronaut will natively handle for us include distributed configuration, service discovery, client-side load balancing, distributed tracing, and serverless functions.

3. The Code

Now that we’ve compared some basic features in the two frameworks, let’s create and compare two applications. To keep things simple, we’ll create a simple REST API that solves basic arithmetic problems. Our service layer will consist of a class that actually does the math for us. Our controller class will contain an endpoint for addition, subtraction, multiplication, and division.

Before we dig into the code, let’s consider a significant difference between Spring Boot and Micronaut. Although the two frameworks provide dependency injection, they go about it differently. Our Spring Boot application handles dependency injection at runtime using reflection and proxies. In contrast, our Micronaut application builds dependency injection data when it’s compiled.

3.1. The Spring Boot Application

First, let’s define a class in our Spring Boot application called ArithmeticService:

@Service
public class ArithmeticService {
    public float add(float number1, float number2) {
        return number1 + number2;
    }
    
    public float subtract(float number1, float number2) {
        return number1 - number2;
    }
    
    public float multiply(float number1, float number2) {
        return number1 * number2;
    }
    
    public float divide(float number1, float number2) {
        if (number2 == 0) {
            throw new IllegalArgumentException("'number2' cannot be zero");
        }
        return number1 / number2;
    }
}

Next, let’s create our REST controller:

@RestController
@RequestMapping("/math")
public class ArithmeticController {
    @Autowired
    private ArithmeticService arithmeticService;
    
    @GetMapping("/sum/{number1}/{number2}")
    public float getSum(@PathVariable("number1") float number1, @PathVariable("number2") float number2) {
    	return arithmeticService.add(number1, number2);
    }
    
    @GetMapping("/subtract/{number1}/{number2}")
    public float getDifference(@PathVariable("number1") float number1, @PathVariable("number2") float number2) {
    	return arithmeticService.subtract(number1, number2);
    }
    
    @GetMapping("/multiply/{number1}/{number2}")
    public float getMultiplication(@PathVariable("number1") float number1, @PathVariable("number2") float number2) {
    	return arithmeticService.multiply(number1, number2);
    }
    
    @GetMapping("/divide/{number1}/{number2}")
    public float getDivision(@PathVariable("number1") float number1, @PathVariable("number2") float number2) {
    	return arithmeticService.divide(number1, number2);
    }
}

Our controller has an endpoint for each of the four arithmetic functions.

3.2. The Micronaut Application

Now, let’s create the service layer of our Micronaut application:

@Singleton 
public class ArithmeticService {
    // implementation identical to the Spring Boot service layer
}

Next, we’ll write our REST controller with the same four endpoints as the Spring Boot applications:

@Controller("/math")
public class ArithmeticController {
    @Inject
    private ArithmeticService arithmeticService;
    
    @Get("/sum/{number1}/{number2}")
    public float getSum(float number1, float number2) {
    	return arithmeticService.add(number1, number2);
    }
    
    @Get("/subtract/{number1}/{number2}")
    public float getDifference(float number1, float number2) {
    	return arithmeticService.subtract(number1, number2);
    }
    
    @Get("/multiply/{number1}/{number2}")
    public float getMultiplication(float number1, float number2) {
    	return arithmeticService.multiply(number1, number2);
    }
    
    @Get("/divide/{number1}/{number2}")
    public float getDivision(float number1, float number2) {
    	return arithmeticService.divide(number1, number2);
    }
}

We can see a lot of similarities between our very simple example applications. In terms of differences, we see that Micronaut takes advantage of Java’s annotations for injection whereas Spring Boot has its own.  Additionally, our Micronaut REST endpoints don’t require any special annotations on the path variables passed into the methods.

3.3. Basic Performance Comparison

Micronaut advertises fast start-up times, so let’s compare our two applications.

First, let’s fire up the Spring Boot application and see how long it takes:

[main] INFO  c.b.m.v.s.CompareApplication - Started CompareApplication in 3.179 seconds (JVM running for 4.164)

Next, let’s see how quickly our Micronaut application starts:

21:22:49.267 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 1278ms. Server Running: http://localhost:57535

We can see that our Spring Boot application starts up in just over three seconds and a little over one second in Micronaut.

Now that we’ve looked at start-up time, let’s exercise our APIs a bit and then check some basic memory statistics. We’ll use the default memory settings when we start our applications.

We’ll start with the Spring Boot application. First, let’s call each of the four arithmetic endpoints and then pull our memory endpoint:

Initial: 0.25 GB 
Used: 0.02 GB 
Max: 4.00 GB 
Committed: 0.06 GB 

Next, let’s run through the same exercise with our Micronaut application:

Initial: 0.25 GB 
Used: 0.01 GB 
Max: 4.00 GB 
Committed: 0.03 GB

In this limited example, both our applications use little memory, but the Micronaut uses about half as much as the Spring Boot application.

4. Comparison

There is no single “best” framework for all applications. The best choice will depend on the specific requirements of the application and the preferences of the developers.

However, the following table can provide some information that may be helpful in making a decision:

Features Micronaut Spring Boot
Size Smaller JAR files Larger JAR Files
Actuator No support Yes, which provides health checks, metrics, and more
Build time Faster Slower
Startup time Faster build time Slower build time
Performance Much better than Spring boot OK
Native image Yes No default support
Auto Configuration Less More
Starter dependencies Fewer starter dependencies More starter dependencies
Dependency injection Annotation-based Property-based
Community Smaller community Larger community
Documentation Good documentation Excellent documentation

5. Conclusion

In this article, we compared Spring Boot with Micronaut. First, we started with an overview of what the two frameworks are. Then, we went through several features and compared the options. Finally, we pitted two simple example applications against each other. We took a look at the code for both applications and then looked at start-up and memory performance.

As always, the example code is available over on GitHub for both the Spring Boot and the Micronaut application.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
3 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.