SpringBoot Cache Caffeine Usage Resolution
- 2021-11-14 05:48:25
- OfStack
Differences between Redis and Caffeine
Similarity
Both are cached ways
Differences
redis is a distributed cache that stores data into the memory of the redis server over the network caffeine is to store data in local applications Compared with redis, caffeine has no consumption on network IO
Contact
1, the two are combined to form a 12-level cache. The usage process is roughly as follows: First, look for data in level 1 cache (caffeine-local application), If not, look for data in level 2 cache (redis-memory). No more, go to the database to find data (database-disk)
Spring Boot Cache Caffeine Use
1. Dependencies to add
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.6</version>
</dependency>
2. Configuration
Configure Caffeine in SpringBoot to control cache behavior (such as expiration time, cache size limit, etc.)
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
@EnableCaching // Turn on the cache
public class CaffeinConfig {
@Bean
// Configure Caffeine Cache behavior (such as expiration, cache size limit, etc.)
public Caffeine caffeineConfig() {
Caffeine caffeine = Caffeine.newBuilder()
.expireAfterWrite(60, TimeUnit.MINUTES)
.maximumSize(1000);
return caffeine;
}
@Bean
public CacheManager cacheManager(Caffeine caffeine) {
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCaffeine(caffeine);
return caffeineCacheManager;
}
}
Caffeine configuration instructions:
initialCapacity=[integer]
Initial cache space size
maximumSize=[long]
Maximum number of caches
maximumWeight=[long]
Maximum weight of cache
expireAfterAccess=[duration]
Expired by a fixed time after the last write or access
expireAfterWrite=[duration]
Expired by a fixed time after the last write
refreshAfterWrite=[duration]
Refresh the cache at fixed intervals after creating the cache or last updating the cache
recordStats
: Develop statistical functions
Note:
When expireAfterWrite and expireAfterAccess exist at the same time, expireAfterWrite shall prevail.
maximumSize and maximumWeight cannot be used together
3. Use the Caffeine cache
Example 1:
Annotate on the method with @ Cacheable (cacheNames = "xxx") or @ Cacheable (value = "xxx").
@Cacheable(value = "caffeinSet_Value")
public String caffeinSetValue(Integer number) {
String str = number % 2 == 0 ? number + " Is an even number " : number + " Is an odd number ";
return str;
}
caffeinSetValue, caffeinSet_Value cache according to the incoming number to find whether there is a matching cache, if there is a direct return results; If not, execute the method, add the result to the cache after execution, and return directly if it matches next time.
Example 2:
When there are multiple parameters, key can be used in the @ Cacheable annotation to select parameters to determine whether the cache exists. You can use condition for conditional filtering, and only those that meet the criteria will be added to the cache.
/**
* number Is even, and the cached key Is incoming number Value
*/
@Cacheable(value = "caffeinSet_Value", key = "#number", condition = "#number%2==0")
public String caffeinSetValue(Integer number,String st) {
String str = number % 2 == 0 ? number + " Is an even number " : number + " Is an odd number ";
return str+st;
}
Note: If the parameter number is 2, first judge whether key is 2 in the caffeinSet_Value cache, and then directly return the result. If not, the method is executed, because satisfying the conditions of condition will eventually add the result to the cache.
If the parameter number passed in is odd, the method is executed every time, because condition is not met and will not be added to the cache.
Example 3:
@Cacheable(value = "caffeinSet_Value", key = "#student.name", condition = "#student.age>10")
public Student caffeinSetValue(Student student,Integer number) {
System.out.println(11111);
return student;
}
According to student object name to caffeinSetValue cache search. The results are cached only if the age in the student object is greater than 10.
Note:
One method A is tuned to another method B with cache annotation in one class, so it is not cached.
For example, if invalidCache calls caffeinSetValue in the same CaffeinConsumer class, cache is not taken, and cache is not effective;
@Service
public class CaffeinConsumer {
public String invalidCache(Integer number,String st) {
String str = caffeinSetValue(number,st);
return str;
}
/**
* number Is even, and the cached key Is incoming number Value
*/
@Cacheable(value = "caffeinSet_Value", key = "#number", condition = "#number%2==0")
public String caffeinSetValue(Integer number,String st) {
String str = number % 2 == 0 ? number + " Is an even number " : number + " Is an odd number ";
return str+st;
}
}
Solution:
1. Take the CacheManger object of Ehcache directly without annotation, and put the data to be cached in it, similar to using Map, and the cache logic is controlled by itself; Or you can use the cache method of redis to add cache;
2. Place method A and method B in two different classes. For example, if both methods are in the same service interface, place method B in another service, so that you can use the cache of B method by tuning B method in A method.
Caffeine Other Commonly Used Notes
1. @ CachePut:
The method annotated with @ CachePut does not check whether the results of previous execution exist in the cache before execution, but executes the method every time and stores the execution results in the specified cache in the form of key-value pairs.
2. @ CacheEvict:
@ CacheEvict is used to annotate on methods or classes that need to clear cached elements. When the tag is on a class, it means that the execution of all the methods in it will trigger the cache clearing operation.
The @ CacheEvict properties you can specify are value, key, condition, allEntries, and beforeInvocation. The semantics of value, key and condition are similar to the corresponding attributes of @ Cacheable.
That is, value indicates which Cache (corresponding to the name of Cache) the cleanup operation occurs on; key indicates which key needs to be cleared. If it is not specified, key generated by default policy will be used; condition represents the condition under which the cleanup operation occurs. If you want to clear all caches, you can use the attribute allEntries=true
Manually add, get and delete caches
The above examples use annotations to cache operations, and sometimes we need to add, delete and modify the cache operations in one method:
1. Get data from the cache
Suppose the key added to the cache named "caffeinSet_Value" in example 2 above is 8 and the value is "8 is even! ! ".
Get this cache manually below:
@Autowired
CacheManager cacheManager;
public String caffeinGetValue() {
Cache cache = cacheManager.getCache("caffeinSet_Value");
// Gets the cache name. name For caffeinSetValue
String name = cache.getName();
// Get caffeinSetValue Built in the cache is 8 Cache of
Cache.ValueWrapper value = cache.get(8);
String str ="";
if (null != value) {
// Gets the value, 8 Is an even number !!
str = String.valueOf(value.get());
}
return str;
}
2. Add data to the cache
@Autowired
CacheManager cacheManager;
public String caffeinPutValue() {
Cache cache = cacheManager.getCache("caffeinSet_Value");
// Gets the cache name. name For caffeinSetValue
String name = cache.getName();
/*
// To the cache put Data. If it doesn't exist key Yes 20 Will join
cache.putIfAbsent(number, " Add a test ");
*/
// To the cache put Data. If it exists key Yes 20 Overwrites the original data
cache.put(20,"20 It's even! ! ");
return " Success ";
}
3. Delete data from the cache
Delete a cache in the caffeinSet_Value cache:
@Autowired
CacheManager cacheManager;
public String caffeinDeleteValue() {
Cache cache = cacheManager.getCache("caffeinSet_Value");
// Gets the cache name. name For caffeinSetValue
String name = cache.getName();
// Only 20 This data will be deleted only if it exists
boolean bo = cache.evictIfPresent(20);
return String.valueOf(bo);
}
Delete all caches in the caffeinSet_Value cache:
@Autowired
CacheManager cacheManager;
public String caffeinDeleteAllValue() {
Cache cache = cacheManager.getCache("caffeinSet_Value");
// Gets the cache name. name For caffeinSetValue
String name = cache.getName();
// Delete caffeinSet_Value All caches in
boolean bo = cache.invalidate();
return String.valueOf(bo);
}