Spring Boot Caffeine Caching Example Configuration
Expensive (CPU or I/O) bound operations can slow down your system. Caching is a way to improve the performance of your system. In this tutorial we demonstrate Caffeine Caching using Spring-Boot. You can use caffeine as a caching provider on top of the spring framework caching abstraction.
Maven Dependencies
We use Apache Maven to manage our project dependencies. To start, add the following dependencies to your project. In this example we use com.github.ben-manes.caffeine-caffeine as the cache provider.
<?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.memorynotfound.springboot.caching</groupId> <artifactId>caffeine</artifactId> <version>1.0.0-SNAPSHOT</version> <url>https://memorynotfound.com</url> <name>Spring Boot - ${project.artifactId}</name> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> </parent> <dependencies> <!-- Spring Framework Caching Support --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <!-- caching provider --> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Caffeine Caching Service Example
To demonstrate caffeine caching with the spring framework, we wrote a simple service that’ll cache the result based on a condition. Let’s start by defining the interface.
package com.memorynotfound.springboot; public interface MusicService { String play(final String instrument); }
The following service is annotated with the @CacheConfig annotation and uses two caches directory and instruments. The play method is annotated with the @Cacheable annotation given a condition parameter, meaning that the outcome of this method’ll be cached upon subsequent invocations when the condition is evaluated to true.
package com.memorynotfound.springboot; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.*; import org.springframework.stereotype.Service; @Service @CacheConfig(cacheNames = {"directory", "instruments"}) public class MusicServiceIml implements MusicService { private static Logger log = LoggerFactory.getLogger(MusicServiceIml.class); @Cacheable(condition = "#instrument.equals('trombone')") public String play(String instrument) { log.info("Executing: " + this.getClass().getSimpleName() + ".play(\"" + instrument + "\");"); return "paying " + instrument + "!"; } }
Configure Caffeine Cache
We configure caffeine by using the application.yml file. We can create cache directories by appending a comma-separated list to the spring.cache.cache-names configuration property. We can define custom specifications using the spring.cache.caffeine.spec configuration property.
CaffeineSpec supports the following configuration properties:
- initialCapacity=[integer]: Sets the minimum total size for the internal hash tables. Provide a large enough estimate at construction time avoids the need for expensive resizing operation later, but setting this value unnecessarily high wastes memory.
- maximumSize=[long]: Specifies the maximum number of entries the cache may contain. Note that the cache may evict an entry before this limit is exceeded or temporarily exceed the threshold while evicting. This feature cannot be used in conjunction with maximumWeight.
- maximumWeight=[long]: Specifies the maximum weight of entries the cache may contain. Note that the cache may evict an entry before this limit is exceeded or temporarily exceed the threshold while evicting. This feature cannot be used in conjunction with maximumSize.
- expireAfterAccess=[duration]: Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the entry’s creation.
- expireAfterWrite=[duration]: Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the entry’s creation, or the most recent replacement of its value.
- refreshAfterWrite=[duration]: Specifies that active entries are eligible for automatic refresh once a fixed duration has elapsed after the entry’s creation, or the most recent replacement of its value.
Durations are represented by an integer, followed by one of “d”, “h”, “m”, or “s”, representing days, hours, minutes, or seconds respectively. There is currently no syntax to request expiration in milliseconds, microseconds, or nanoseconds.
spring: cache: cache-names: instruments, directory caffeine: spec: maximumSize=500, expireAfterAccess=30s logging: pattern: console: "%-5level - %msg%n" level: - error - com.memorynotfound=trace
The equivalent application.properties file:
spring.cache.cache-names: instruments, directory spring.cache.caffeine.spec: maximumSize=500, expireAfterAccess=30s logging.pattern.console=%-5level - %msg%n logging.level.com.memorynotfound=trace logging.level.=error
Testing Caffeine Cache
To demonstrate if our methods are using the cache, we wrote a simple application. The play method is executed multiple times.
package com.memorynotfound.springboot; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @EnableCaching @SpringBootApplication public class Application implements CommandLineRunner { private static Logger log = LoggerFactory.getLogger(Application.class); @Autowired private MusicService musicService; public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws Exception { log.info("Spring Boot Caffeine Caching Example Configuration"); play("trombone"); play("guitar"); play("trombone"); play("bass"); play("trombone"); } private void play(String instrument){ log.info("Calling: " + MusicServiceIml.class.getSimpleName() + ".play(\"" + instrument + "\");"); musicService.play(instrument); } }
Console Output
The previous application prints the following output to the console. We can clearly see that the MusicServiceIml.play("trombone"); is cached.
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.4.RELEASE) INFO - Spring Boot Caffeine Caching Example Configuration INFO - Calling: MusicServiceIml.play("trombone"); INFO - Executing: MusicServiceIml.play("trombone"); INFO - Calling: MusicServiceIml.play("guitar"); INFO - Executing: MusicServiceIml.play("guitar"); INFO - Calling: MusicServiceIml.play("trombone"); INFO - Calling: MusicServiceIml.play("bass"); INFO - Executing: MusicServiceIml.play("bass"); INFO - Calling: MusicServiceIml.play("trombone");
Download
From:一号门
COMMENTS