Micronaut Caffeine Cache - Quick Start
Hello everyone, Today we will setup up a sample Micronaut application and integrate it with Caffeine Cache. Caffeine is a high-performance Java-based caching library providing a near-optimal hit rate. It provides an in-memory cache.
Final Project Directory
Maven Dependencies
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.knf.dev.demo</groupId>
<artifactId>micronaut-caffeine-demo</artifactId>
<version>0.1</version>
<packaging>${packaging}</packaging>
<parent>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-parent</artifactId>
<version>3.1.1</version>
</parent>
<properties>
<packaging>jar</packaging>
<jdk.version>11</jdk.version>
<release.version>11</release.version>
<micronaut.version>3.1.1</micronaut.version>
<exec.mainClass>com.knf.dev.demo.Application</exec.mainClass>
<micronaut.runtime>netty</micronaut.runtime>
</properties>
<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-validation</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micronaut.test</groupId>
<artifactId>micronaut-test-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-http-client</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-http-server-netty</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-runtime</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micronaut.cache</groupId>
<artifactId>micronaut-cache-caffeine</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.micronaut.build</groupId>
<artifactId>micronaut-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- Uncomment to enable incremental compilation -->
<!-- <useIncrementalCompilation>false</useIncrementalCompilation> -->
<annotationProcessorPaths combine.children="append">
<path>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-http-validation</artifactId>
<version>${micronaut.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Amicronaut.processing.group=com.knf.dev.demo</arg>
<arg>-Amicronaut.processing.module=micronaut-caffeine-demo</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
Configure the caches in application.yml
micronaut:
caches:
companydetails:
maximumSize: 20
charset: UTF-8
Cache Provider
Imagine a service that retrieves company details by name. This operation may be expensive and you may want to cache it.
package com.knf.dev.demo.cacheprovider;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import io.micronaut.cache.annotation.CacheConfig;
import io.micronaut.cache.annotation.Cacheable;
import jakarta.inject.Singleton;
@Singleton
@CacheConfig("companydetails")
public class CompanyDataProvider {
Map<String, Map<String, String>> companydetails =
new HashMap<String, Map<String, String>>() {
/**
*
*/
private static final long serialVersionUID = 1L;
{
put("A-Company",
Map.of("Number of Employees", "300", "Rating", "4"));
put("B-Company",
Map.of("Number of Employees", "200", "Rating", "4.2"));
}
};
@Cacheable
public Map<String, String> companydetails(String name) {
try {
TimeUnit.SECONDS.sleep(2);
return companydetails.get(name);
} catch (InterruptedException e) {
return null;
}
}
}
Company.java
package com.knf.dev.demo.model;
import java.util.Map;
import io.micronaut.core.annotation.Introspected;
@Introspected
public class Company {
private String name;
private Map<String, String> details;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, String> getDetails() {
return details;
}
public void setDetails(Map<String, String> details) {
this.details = details;
}
public Company(String name, Map<String, String> details) {
super();
this.name = name;
this.details = details;
}
public Company() {
}
}
Controller
package com.knf.dev.demo.controller;
import com.knf.dev.demo.cacheprovider.CompanyDataProvider;
import com.knf.dev.demo.model.Company;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
@Controller("/api")
public class DemoController {
private final CompanyDataProvider companyDataProvider;
public DemoController(CompanyDataProvider companyDataProvider) {
this.companyDataProvider = companyDataProvider;
}
@Get("/{companyName}")
public Company index(String companyName) {
return new Company(companyName, companyDataProvider.
companydetails(companyName));
}
}
Main Class
package com.knf.dev.demo;
import io.micronaut.runtime.Micronaut;
public class Application {
public static void main(String[] args) {
Micronaut.run(Application.class, args);
}
}
Running the Application
Run as Java Application or
mvn mn:run
mvn mn:run