---
title: "How to Integrate Spring With Micronaut"
description: "Micronaut supports many Spring features. This lets you use it for specific environments requiring small memory footprints and quick start times"
date: 2019-05-29
author: "Nicolas Fränkel"
tags: ["development","java","serverless"]
url: https://www.exoscale.com/blog/how-to-integrate-spring-with-micronaut/
---
# How to Integrate Spring With Micronaut

We've talked about Micronaut in the past, and its [Ahead-of-Time compilation approach to efficiently use Java in Serverless functions](https://www.exoscale.com/blog/java-serverless-micronaut-graalvm/).

Thanks to AOT, Micronaut removes the limitations of Java in that domain, _e.g_ the long startup times that would affect FaaS performance.

We've mentioned how Micronaut is actually compatible with Spring, making it possible to write applications that run in both runtimes. That means you can take advantage of the Spring features to create applications adapted to _e.g._ embedded devices, memory-limited environments and of course function as a service.

Let's explore how Spring an Micronaut go along, starting from our [previous post](https://www.exoscale.com/blog/java-serverless-micronaut-graalvm/) code base, and migrating it to Spring bit by bit.

![Integrate Spring With Micronaut](https://www.exoscale.com/blog/how-to-integrate-spring-with-micronaut/micronaut-spring.jpg)

## The Spring @Component Annotation

The first baby step is actually to replace the JSR 330 `@Singleton` annotation by Spring's `@Component` annotation.
At compile time, Micronaut will take care of the translation, from Spring to JSR 330.

To start using Spring annotations in a Micronaut app two configuration steps are required:

1. The first step is to add a dependency to the `micronaut-spring` JAR.
It contains some utility classes and AOT-compiled Micronaut-compatible classes for Spring.
It also has a transitive dependency to `spring-context`, which contains the standard `@Component`, `@Bean`, `@Configuration`, etc. Spring annotations.

        <dependency>
            <groupId>io.micronaut</groupId>
            <artifactId>micronaut-spring</artifactId>
        </dependency>

2. The second step is to let Micronaut process those annotations.
To allow that, just add another annotations processor:

        <path>
            <groupId>io.micronaut.spring</groupId>
            <artifactId>micronaut-spring-annotation</artifactId>
            <version>1.0.0.RC1</version>
        </path>

At this point, `@Singleton` can be replaced with `@Component`, and Micronaut will take care of the "translation" from the latter to the former.

## Making Configuration Orthogonal

Autowiring is the process of creating beans, either through the good old XML or by annotating the classes and letting auto-scan find them, and hoping that dependencies between them will be fulfilled.
For that to happen, there should be one and only one candidate bean for every dependency.
A more rigorous approach would be to make everything explicit, by injecting the required bean manually, instead of letting the container choose.

In Spring, this can be done by creating a _configuration_ class, which is any class annotated with `@Configuration`.
Inside this class, every method annotated with `@Bean` will contribute its return value as a bean to the context.

Let's make our configuration orthogonal to the classes themselves:

1. Remove `@Component` on classes `Foo` and `Bar`
2. Create the `@Configuration`-annotated class:

        @Configuration
        public class AppConfig {
        
            @Bean
            public Bar bar() {
                return new Bar(new Foo());
            }
        }

This is equivalent to the previous setup from a result point of view, but the concept of the bean is decoupled from its underlying class.
For example, one could create another `Bar` bean named differently.

## Use More Spring Features in Micronaut

While focusing only on a subset of Spring, Micronaut [supports many of the Spring features](https://micronaut-projects.github.io/micronaut-spring/latest/guide/index.html), allowing to easily migrate an existing Spring application.

For example, standard Spring dependency-injection works as expected:

    @Configuration
    public class AppConfig {

        @Bean
        public Foo foo() {
            return new Foo();
        }
    
        @Bean
        public Bar bar(Foo foo) { // Micronaut will find the Foo bean in the context and inject it
            return new Bar(foo);
        }
    }

Likewise, it is possible to externalize the values returned by the `Foo` and `Bar` classes into an `application.yml` file, for easier maintenance.

    app:
      bar: "Bar"
      foo: "Foo"

To read such a file, Spring provides the _configuration property_ mechanism:
create a class annotated with `@ConfigurationProperties`, whose structure matches the YAML file, and Spring will fill the values from the file to a class instance for you.

    @ConfigurationProperties("app")
    public class MicronautConfigProperties {
    
        private String foo;
        private String bar;

        // Getters and setters    
    }

At that point, an instance of that class can be injected into the `@Bean`-annotated method to get its value, and then be passed to the relevant bean:

    @Configuration
    public class MicronautConfig {

        @Bean
        public Foo foo(MicronautConfigProperties props) {
            return new Foo(props);
        }
    }

    public class Foo {
    
        private final String label;
    
        public Foo(MicronautConfigProperties props) {
            label = props.getFoo();  // With the previous YAML, this will be initialized with "Foo"
        }
    
        public String foo() {
            return label;
        }
    }

## Exposing the Integrated Netty HTTP Server

The next goal in our migration journey is to provide some kind of HTTP endpoint, so that we can send requests to our application.
By default, Micronaut offers Netty as an embedded non-blocking HTTP server:

1. Add the Micronaut Netty module as a dependency:

        <dependency>
            <groupId>io.micronaut</groupId>
            <artifactId>micronaut-http-server-netty</artifactId>
        </dependency>

2. Change the way the application is launched.
Because it's to become an HTTP server, the process shouldn't end, but wait and listen to requests.

    Add the Micronaut runtime dependency:

        <dependency>
            <groupId>io.micronaut</groupId>
            <artifactId>micronaut-runtime</artifactId>
        </dependency>

    Update the `main()` method:

        public static void main(String[] args) {
            Micronaut.run(Main.class);
        }

    Micronaut is able to detect the Netty dependency added previously, and launch the application as a never-ending listening process.

At this point, everything is ready to add endpoints.

I assume you're already familiar with Spring MVC, but as a quick reminder, to create an endpoint in Spring MVC, annotate a class with `@Controller` and one of its method with `@RequestMapping`.
Also, one can use dedicated `@GetMapping`, `@PostMapping`, etc. annotations for refined semantics regarding the HTTP method.

Finally, to return a serialized object - instead of returning a reference to a view - the `@RestController` can be used in place of `@Controller` and additional configuration.

The following code is a sample of such a controller:

    @RestController
    public class BarController {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(BarController.class);
    
        private final Bar bar;
    
        public BarController(Bar bar) {
            this.bar = bar;
        }
    
        @GetMapping("/")
        public void root() {
            LOGGER.info(bar.bar());
        }
    }

If a `GET` request is made to the root (`/`) of the server, the `root()` method should be called.

This works in the context of a Spring application.
To make our application "compliant", one needs to annotate the `Main` class with the `@SpringBootApplication` annotation:

    @SpringBootApplication
    public class Main {
    
        public static void main(String[] args) {
            Micronaut.run(Main.class);
        }
    }

This also works with any other class situated in the same package - but the convention is to annotate the class that hosts the `main()` method.

Just as before, Micronaut needs to "translate" those new Spring annotations into its own model.
Since they come from other JARs, we need to hook additional annotation-processors into the build process, one for each JAR exposing the annotations:

    <path>
        <groupId>io.micronaut.spring</groupId>
        <artifactId>micronaut-spring-boot-annotation</artifactId>
        <version>1.0.0.RC1</version>
    </path>
    <path>
        <groupId>io.micronaut.spring</groupId>
        <artifactId>micronaut-spring-web-annotation</artifactId>
        <version>1.0.0.RC1</version>
    </path>

## Returning JSON From the Endpoint

Usually, when a request is made to an endpoint, one expects a response:
it might be raw text, an HTLM document, an image, etc. but never `void` in our simple example.
By just changing the `void` return type to `String`, and actually returning a `String` instance, the response wraps the later and it's displayed to the user:

    @GetMapping("/")
    public String root() {
        return bar.bar();
    }

Even if your architecture is not based on microservices, chances are you're probably consuming - or even providing - some kind of webservices.
Nowadays, those are mostly REST-based, with JSON as the widespread exchange format.
In Spring MVC, when an entity is returned, the framework takes responsibility to serialize it to JSON, with the help of [Jackson](https://github.com/FasterXML/jackson).
If some customization is required during serialization, hooks are available for that:
annotations on the entity class, custom serializer dedicated to a class, etc.
It happens exactly the same way in Micronaut.
Let's change the method signature:

    @GetMapping("/")
    public Bar root() {
        return bar;
    }

If a query is sent to the endpoint at that point, the server will return an error:
`Error encoding object [com.exoscale.syslog.micronaut.Bar@14b72eb8] to JSON: No serializer found for class com.exoscale.syslog.micronaut.Bar and no properties discovered to create BeanSerializer`.
The reason is that the `Bar` class doesn't follow the JavaBean specification:
it has no getters.

In order to fix this error, we need to think about the desired result, something akin to:

    {
      "bar":"FooBar"
    }

Because we are using Spring MVC, we have out-of-the-box Jackson integration.
Jackson offers a way to customize the serialization of specific class via so-called _serializers_.
To register such a serializer, just create a class implementing `JsonSerializer` and register it as a bean:

    @Configuration
    public class MicronautConfig {
    
        @Bean
        public JsonSerializer<Bar> serializer() {
            return new JsonSerializer<Bar>() {
                @Override
                public void serialize(Bar bar, JsonGenerator generator, SerializerProvider provider) throws IOException {
                    generator.writeStartObject();
                    generator.writeFieldName("bar");
                    generator.writeString(bar.bar());
                    generator.writeEndObject();
                }
            };
        }
        
        // Other beans
    }

The result of calling the endpoint is now:

    {"bar":"FooBar"}

Spring MVC offers a declarative way to format the returned JSON.
Just add the following snippet into the `application.yml` file:

    jackson:
      serialization:
        indentOutput: true

Alternatively, if you prefer the properties file format, add `jackson.serialization.indentOutput=true` to the `application.properties` file.

With that configuration, the returned JSON now perfectly matches our specifications:

    {
      "bar":"FooBar"
    }

## Conclusion

Micronaut is able not only to work its magic on its own, but also to integrate with Spring, Spring MVC and Spring Boot.

While not all features work (_e.g._ Spring Data), for many use-cases it will allow you write complete and rich applications using the Spring framework.

Everything described above works perfectly once processed by Graal VM, in order to create native executables permitting to target specific environments requiring small memory footprints and quick start times.

The complete sourcecode is available on [Exoscale Labs Github repository](https://github.com/exoscale-labs/micronaut-from-scratch).

