theme: OCI White slidenumbers: false [.hide-footer]
Getting the best out of Grails 4 and Micronaut
- Graeme Rocher
- Creator of Grails and Micronaut
- Principal Engineer at Object Computing
- Oracle Groundbreaker Award Winner
- Introduction to Micronaut
- Introduction to Grails 4
- Grails vs Micronaut
- Using Micronaut Features in Grails
- Demos
- Micronaut a Foundational Library for building applications of any type
- Focuses on Small Memory Footprint and Speed
- Eliminates Reflection, Runtime Proxies and Runtime Analysis
- Micronaut is uses no reflection, no runtime proxies, no runtime byte code generation etc.
- Eliminating these leads to reduced memory consumption and faster startup
- Increasingly important for Microservices, Serverless, IoT, any low-memory footprint environment
Micronaut | Grails |
---|---|
Range of Runtimes | Servlet Only |
General Purpose | Traditional Servlet Web Apps |
DI, AOP etc. | Spring for DI, AOP etc. |
Java, Kotlin, Groovy, GraalVM | Groovy Only |
Client and Server | Server Only |
- Micronaut the Parent
ApplicationContext
- Made possible by
- Micronaut Libraries become usable in Grails
- Anything we build for Micronaut benefits Grails
- Build Configurations (Instead of Plugins)
- Use Declarative Clients
- HTTP
- Kafka
- RabbitMQ
- Consider Building Configurations instead of Plugins
- Work with Micronaut, Spring (with
micronaut-spring
) and Grails - Plugins only work with Grails
- ... although some things only possible with Plugins (Views, taglibs etc.)
- Configuration with
@ConfigurationProperties
- Beans with
@Singleton
,@Factory
etc. - Conditional Behaviour with
@Requires
- Customization with
@Replaces
@ConfigurationProperties("example")
class ExampleConfiguration {
String name
}
ApplicationContext context = ApplicationContext.run("example.name":"Demo")
FooConfiguration config = context.getBean(FooConfiguration)
assert config.name == 'Demo'
@Requires(property="example.enabled")
@Requires(beans=DataSource)
@Requires(missingBeans=Example)
@Singleton
class DefaultExampleBean implements Example {
...
}
def context = ApplicationContext.run("example.enabled":"true")
Example example = context.getBean(Example)
@Replaces(DefaultExample)
@Singleton
class AlternativeExample implements Example {
...
}
- Types match much
- Beans annotated with
@Infrastructure
not replaceable
@Client("https://api.github.com")
@Header(name="User-Agent", value="micronaut-client")
interface GithubClient {
@Get("/repos/{+slug}")
Info getInfo(String slug)
}
- Blocking or Non-Blocking (RxJava, Reactor or Future)
- Reflection / Runtime Proxy Free
- Uses Micronaut's low-level HTTP client (
RxHttpClient
) under the hood - Built with Micronaut AOP (reflection/runtime proxy free)
- Works on GraalVM
nativeimage
- Integrates with Tracing, Metrics, Service Discovery etc.
@KafkaClient
public interface ProductClient {
@Topic("my-products")
void sendProduct(@KafkaKey String brand, String name);
}
- Blocking or Non-Blocking (RxJava, Reactor or Future)
@RabbitClient("animals")
interface AnimalClient {
void send(@Header String animalType, Animal animal)
}
- Blocking or Non-Blocking (RxJava, Reactor or Future)
- Micronaut Supports Message-Drive Microservices
- Can be run as standalone processes (No HTTP server)
- Use
@RabbitListener
for Rabbit - Use
@KafkaListener
for Kafka
- Compile Time
- Reflection and Runtime Proxy Free
- Java, Groovy or Kotlin
- Built with Micronaut AOP
- Micronaut Provides an Awesome Foundation
- Building Blocks to Create Libraries, Configurations and Clients
- Most Micronaut Features Available in Grails
- Build Micronaut Libraries not Plugins