1 Introduction
This article describes how to use caching in spring-boot projects. Through this article, you can learn:
- How to get started with Spring Cache quickly;
- How to choose a cache storage component;
- How to use various common cache components.
A spring-boot project should use caching in this way to achieve several goals:
- Improve system access rate;
- Low business code intrusion;
- High scalability/replaceability.
2. Get started quickly
Step0 Preparation
The project is based on spring-boot, or you have already set up a spring-boot project.
Step1 Enable cache
Add the @EnableCaching annotation directly to the entry configuration, that is, enable caching
// SpringCacheDemoApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.*;
@SpringBootApplication
@EnableCaching
public class SpringCacheDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCacheApplication.class, args);
}
}
When using the spring framework but not using spring-boot, please
xxxCacheManager
initialize the cache by yourself. For the initialization code, please refer to the spring-bootxxxCacheConfiguration
class.
Step2 Use cache
Using the cache through annotations is extremely simple, just use the following three annotations on the method:
annotation | illustrate |
---|---|
@Cachable | Lazy cache method return value (commonly used, on annotation query methods) |
@CachePut | Force a cache refresh using the method return value (not commonly used, for cache coherency compensation) |
@CacheEvict | Clean up the cache (commonly used, marked on the modification and deletion methods) |
Don't say anything, just go to the sample code:
// UserService.java
public class UserService {
// 一些本文无关的代码
// ...
// 通过@Cacheable注解,来标记缓存某方法的结果
// 下次相同参数值的调用会直接从缓存中取结果
// value或cacheNames参数,标记此缓存的名称
@Cacheable(value = "user")
public User getOneUser(long userId) {
return dao.getOneUser(userId);
}
// 新增对象时,不需要配置缓存,因为缓存是惰性初始化的,会在首次查询时加载
public void addUser(User user) {
dao.addUser(user);
}
// 使用@CacheEvict清除缓存,推荐更新、删除时,使用此注解
// 此处参数不为userId,因此需要使用'key="#user.userId"'生成缓存键
@CacheEvict(cacheNames = "user", key="#user.userId")
public void updateUser(User user) {
dao.updateOneUser(user);
}
// 使用@CacheEvict配合'allEntries = true'可清理整个user缓存集
// 此时不需要缓存键,当更新多条数据,不确定具体缓存键时,使用此方法
@CacheEvict(cacheNames = "user", allEntries = true)
public void updateUsers(List<User> users) {
dao.updateUsers(users);
}
@CacheEvict(cacheNames = "user", key="#user.userId")
public void deleteUser(long userId) {
dao.deleteOneUser(userId);
}
// 强制刷新某userId的用户缓存
// 不推荐使用——可能会生成无用的缓存,仅当缓存不同步时使用
@CachePut(value = "user")
public int refreshUserCache(long userId) {
return dao.getOneUser(userId);
}
}
After the above steps, you have successfully added and enabled caching for your code.
If you want to ensure the robustness of the cache, you also need to choose aConcurrentHashMap
more reliable storage.
3. Choose a storage implementation
Spring cache comes with a variety of implementations, and third parties also provide a variety of implementations for spring cache.
For mainstream, performance, stability and other reasons, it is recommended to choose one of the following three implementations according to the scenario:
CaffeineCache | RedisCache | J2Cache | |
---|---|---|---|
storage method | local | server | local + server |
performance | extremely high | high | extremely high |
the complexity | Simple | Simple | complex |
distributed | not support | support | support |
Applicable scene | Stand-alone deployment preferred | distributed | Medium and low scale distributed |
4. Caffeine local cache
4.1 Introduction
Caffeine
Compared with the default storage ConcurrentHashMap
, it is more robust and has higher performance, and provides more cache control strategies. It can prevent memory leaks through eviction strategies and alleviate consistency problems through timeout strategies.
Caffeine
It is known as the most efficient memory cache component under java:
4.2 Applicable scenarios
It is the first choice for single-machine applications, which is very simple and efficient, but it is not suitable for multi-machine deployment scenarios such as load balancing.
4.3 How to use
To use spring-boot, you Caffeine
only need to add two configurations to the default configuration:
Caffeine
Dependencies introduced by Step1
<!-- pom.xml -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
Step2 Configure through Spring configuration fileCaffeine
# 因配置类CaffeineCacheConfiguration竞争不过RedisCacheConfiguration等
# 为防止不可预测的缓存配置,建议显示配置缓存类型为caffeine
spring.cache.type=caffeine
# caffeine的配置,使用单个字符串即可完成
# 建议设置缓存大小,及超时时间
spring.cache.caffeine.spec=maximumSize=500, expireAfterWrite=1m
# 更多配置可参考CaffeineSpec类
5. Redis server cache
5.1 Introduction
Compared with local cache, using Redis as the storage server can break through the limitation of single machine and provide cache support for multi-server and distributed deployment. As an in-memory database, Redis has performance advantages unmatched by other databases, and is especially suitable as a cache service.
5.2 Applicable scenarios
单Redis
It can support load balancing scenarios with QPS<10W.
读写分离集群
It can support larger-scale distributed scenarios, and the theoretical upper limit is only limited by the frequency of data update.
However, in the case of a single machine, regardless of performance or complexity, it is recommended Caffeine
that with the help of Spring's abstraction, it can be smoothly switched with the deployment architecture Redis
.
5.3 How to use
When the dependency is included spring-data-redis
and the cache is enabled ( @EnableCaching
), spring-boot will choose redis as the underlying storage for the cache.
Under the default configuration of the spring-boot cache, you only need to add or modify the following configurations in the spring configuration file:
# 配置redis地址
spring.redis.host=localhost
spring.redis.password=xxxxxx
# 启用缓存redis键的前缀
spring.cache.redis.use-key-prefix=true
# 配置缓存redis键的前缀,以便将缓存与其它数据区分开
spring.cache.redis.key-prefix=spring-cache-
# 配置缓存的超时时间,注意一定要配置,以保证无内存泄露、减少缓存不同步问题
spring.cache.redis.time-to-live=10m
When only using spring, please add
spring-data-redis
the dependency and refer to theRedisCacheConfiguration
initialization by yourselfRedisCacheManager
.
6. J2Cache secondary cache
6.1 Introduction
J2Cache is a two-level cache component implemented by open source China. It uses the local + server two-level cache mechanism.
- Through the local cache, the network IO overhead can be effectively reduced and the cache efficiency can be improved;
- Using the server cache as the second-level cache effectively reduces the pressure on the database in local cache warm-up scenarios such as deployment;
- At the same time, the message mechanism is used to ensure the synchronization between the local cache and the server cache.
J2Cache official website
6.2 Applicable scenarios
In a medium-scale distributed environment, when you want to use the fastest way to improve performance based on Redis cache, but do not want to add more bandwidth, memory or distributed instances to the Redis server, you can consider J2Cache.
6.3 How to use
J2Cache implements the Spring cache abstraction, so switching to J2Cache with Spring cache default configuration is very simple:
Step1 Introduce J2Cache dependency
maven introduces J2Cache
<!-- pom.xml -->
<dependency>
<groupId>net.oschina.j2cache</groupId>
<artifactId>j2cache-core</artifactId>
<version>xxxxx</version>
</dependency>
Step2 Configure J2Cache cache
@Configuration
@EnableCaching
public class MyCacheConfig extends CachingConfigurerSupport {
@Override
public CacheManager cacheManager() {
// 引入配置
J2CacheConfig config = J2CacheConfig.initFromConfig("/j2cache.properties");
// 生成 J2CacheBuilder
J2CacheBuilder j2CacheBuilder = J2CacheBuilder.init(config);
// 构建适配器
J2CacheSpringCacheManageAdapter j2CacheSpringCacheManageAdapter = new J2CacheSpringCacheManageAdapter(j2CacheBuilder, true);
return j2CacheSpringCacheManageAdapter;
}
}
J2Cache integrated spring-boot configuration example
7. References
- Spring Cache Official Documentation
- Spring boot cache official documentation
- Spring boot cache configuration official documentation
- J2Cache official website