Skip to content

Commit

Permalink
Spring boot vs Micronaut Framework @configuration vs @factory (#1471)
Browse files Browse the repository at this point in the history
  • Loading branch information
sdelamo committed Jun 18, 2024
1 parent 6efea0b commit 98c1740
Show file tree
Hide file tree
Showing 21 changed files with 375 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"title": "Manually define a Bean - Spring Boot to Micronaut Framework",
"intro": "This guide compares how to create a bean in a Spring Boot application with @Configuration vs. in a Micronaut application with @Factory.",
"authors": ["Sergio del Amo"],
"tags": ["spring-boot"],
"categories": ["Spring Boot to Micronaut Framework"],
"publicationDate": "2022-09-13",
"languages": ["java"],
"apps": [
{
"framework": "Spring Boot",
"testFramework": "junit",
"name": "springboot",
"features": ["spring-boot-starter-web"]
},
{
"name": "micronautframework",
"features": []
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package example.micronaut;

public interface Greeter {
String greet();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package example.micronaut;

import io.micronaut.context.annotation.Factory;
import io.micronaut.context.annotation.Bean;

@Factory // <1>
class GreeterFactory {
@Bean
Greeter helloGreeter() {
return new HelloGreeter();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package example.micronaut;

public class HelloGreeter implements Greeter {
@Override
public String greet() {
return "Hello";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2017-2024 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.micronaut;

import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

@MicronautTest // <1>
class GreeterTest {

@Inject // <2>
Greeter greeter;

@Test
void helloGreeterIsInjectedAsBeanOfTypeGreeter() {
assertNotNull(greeter);
assertEquals("Hello", greeter.greet());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
common:header-top.adoc[]

== Sample Project

You can link:@sourceDir@.zip[download a sample application] with the code examples shown in this article.

== Introduction

Both Spring and Micronaut frameworks are dependency injection engines. In this tutorial, we will manually create a bean, a class managed by the bean context.

== An Interface and an Implementation

With an interface such as:

source:Greeter[app=springboot]

and an implementation such as:

source:HelloGreeter[app=springboot]

We want to be able to inject a bean of the type `Greeter` into our application.

There are several ways to do it. In this tutorial, we will manually instantiate the bean in both frameworks.

== Spring @Configuration

Create a https://docs.spring.io/spring-framework/reference/core/beans/java/configuration-annotation.html[`@Configuration` class] to declare `Greeter` bean through a @Bean-annotated method.

source:GreeterFactory[app=springboot]

callout:spring-at-configuration[1]

=== Spring Boot Test

The following test verify it is possible to inject a bean of type `Greeter` in a Spring Boot application.

test:GreeterTest[app=springboot]

callout:spring-boot-test[1]
callout:autowired[number=2,arg0=Greeter]

== Micronaut @Factory

source:GreeterFactory[app=micronautframework]

callout:at-factory[1]

=== Micronaut Test

The following test verify it is possible to inject a bean of type `Greeter` in a Micronaut application.

test:GreeterTest[app=micronautframework]

callout:micronaut-test[1]
callout:injection[number=2,arg0=Greeter]

== Conclusion

This guide illustrate that the APIs `@Configuration` and `@Factory` of both frameworks are almost identical.


== Next steps

Read more https://guides.micronaut.io/latest/tag-spring_boot_to_micronaut.html[Spring Boot to Micronaut] guides.

common:helpWithMicronaut.adoc[]


Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package example.micronaut;

public interface Greeter {
String greet();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package example.micronaut;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration // <1>
class GreeterFactory {

@Bean
Greeter helloGreeter() {
return new HelloGreeter();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package example.micronaut;

public class HelloGreeter implements Greeter {
@Override
public String greet() {
return "Hello";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package example.micronaut;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest // <1>
class GreeterTest {

@Autowired // <2>
Greeter greeter;

@Test
void helloGreeterIsInjectedAsBeanOfTypeGreeter() {
assertNotNull(greeter);
assertEquals("Hello", greeter.greet());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"title": "Mark a class as a bean.- Spring Boot to Micronaut Framework",
"intro": "This guide compares how to mark a class as a bean in a Spring Boot application with @Component vs. in a Micronaut application with @Singleton.",
"authors": ["Sergio del Amo"],
"tags": ["spring-boot"],
"categories": ["Spring Boot to Micronaut Framework"],
"publicationDate": "2022-09-13",
"languages": ["java"],
"apps": [
{
"framework": "Spring Boot",
"testFramework": "junit",
"name": "springboot",
"features": ["spring-boot-starter-web"]
},
{
"name": "micronautframework",
"features": []
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package example.micronaut;

public interface Greeter {
String greet();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package example.micronaut;

import jakarta.inject.Singleton;

@Singleton // <1>
public class HelloGreeter implements Greeter {
@Override
public String greet() {
return "Hello";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2017-2024 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.micronaut;

import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

@MicronautTest // <1>
class GreeterTest {

@Inject // <2>
Greeter greeter;

@Test
void helloGreeterIsInjectedAsBeanOfTypeGreeter() {
assertNotNull(greeter);
assertEquals("Hello", greeter.greet());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
common:header-top.adoc[]

== Sample Project

You can link:@sourceDir@.zip[download a sample application] with the code examples shown in this article.

== Introduction

Both Spring and Micronaut frameworks are dependency injection engines. In this tutorial, we create a bean by "marking" a class as a bean.

== An Interface

With an interface such as:

source:Greeter[app=springboot]

We want to be able to inject a bean of the type `Greeter` into our application.

== Spring Boot @Component

In Spring, we can create an implementation and annotate it with `@Component`.

source:HelloGreeter[app=springboot]

callout:spring-at-component[1]

=== Spring Boot Test

The following test verify it is possible to inject a bean of type `Greeter` in a Spring Boot application.

test:GreeterTest[app=springboot]

callout:spring-boot-test[1]
callout:autowired[number=2,arg0=Greeter]

== Micronaut @Singleton

In Micronaut framework, we can create an implementation and annotate it with `@Singleton`.

source:HelloGreeter[app=micronautframework]

callout:singleton[1]

=== Micronaut Test

The following test verify it is possible to inject a bean of type `Greeter` in a Micronaut application.

test:GreeterTest[app=micronautframework]

callout:micronaut-test[1]
callout:injection[number=2,arg0=Greeter]

== Conclusion

This guide illustrate that marking a class as a bean is similar in both frameworks. Micronaut Framework uses the standard `jakarta.inject.Singleton` and annotation while Spring uses custom annotations.

NOTE: Micronaut Framework generates the necessary information to fulfill the injection points at compilation time.

WARNING: Spring relies on classpath scanning to find classes annotated with @Component. In the Spring Boot application, `HelloGreeter` is detected because the application contains an `Application` with the `@SpringBootApplication` annotation. The `@SpringBootApplication` annotation applies the `@ComponentScan` annotation, which tells Spring to scan the package where the `Application` class is located and its sub-packages

== Next steps

Read more https://guides.micronaut.io/latest/tag-spring_boot_to_micronaut.html[Spring Boot to Micronaut] guides.

common:helpWithMicronaut.adoc[]


Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package example.micronaut;

public interface Greeter {
String greet();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package example.micronaut;
import org.springframework.stereotype.Component;

@Component // <1>
public class HelloGreeter implements Greeter {
@Override
public String greet() {
return "Hello";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package example.micronaut;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest // <1>
class GreeterTest {

@Autowired // <2>
Greeter greeter;

@Test
void helloGreeterIsInjectedAsBeanOfTypeGreeter() {
assertNotNull(greeter);
assertEquals("Hello", greeter.greet());
}

}
1 change: 1 addition & 0 deletions src/docs/common/callouts/callout-at-factory.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A factory is a class annotated with the `@Factory` annotation that provides one or more methods annotated with a bean scope annotation.
2 changes: 2 additions & 0 deletions src/docs/common/callouts/callout-spring-at-component.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The `@Component` annotation indicates that the annotated class is a component.
A class annotate with `@Component` is considered as a candidate for auto-detection when using annotation-based configuration and classpath scanning.
Loading

0 comments on commit 98c1740

Please sign in to comment.