tio-boot 内置 CacheUtils
概述
tio-utils 内置了 CacheUtils 用户提供对缓存数据的支持,提供的工具类如下,tio-boot 已经内置了 tio-utils,所以不需要添加 tio-utils 的依赖.但是需要添加对于缓存库的依赖
- com.litongjava.tio.utils.cache.caffeine.CaffeineCache
- com.litongjava.tio.utils.cache.guava.GuavaCache
- com.litongjava.tio.utils.cache.caffeineredis.CaffeineRedisCache
- com.litongjava.tio.utils.cache.guavaredis.GuavaRedisCache
- com.litongjava.tio.utils.cache.j2cache.J2Cache
- com.litongjava.tio.utils.cache.redis.RedisCache
下面演示一下 CaffeineCache,RedisCache,CaffeineRedisCache 的使用
CacheUtils
com.litongjava.tio.utils.cache.CacheUtils 提供了 get 方法,方法签名如下
public static <T extends Serializable> T get(ICache cache, String cacheKey, boolean putTempToCacheIfNull,FirsthandCreater<T> firsthandCreater);
方法解释:
根据 cacheKey 从缓存中获取对象,如果缓存中没有该 key 对象,则用 firsthandCreater 获取对象,并将对象用 cacheKey 存于 cache 中
缓存数据到 Caffeine
添加依赖
tio-utils 虽然提供了对 caffeine 的支持,但是并没有继承 caffeine 依赖,所以添加 caffeine 依赖,推荐 2.x 版本,因为 3.x 版已经不支持 jdk 1.8
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.9.3</version>
</dependency>
配置类 CacheNameConfig
CacheName,使用默认的 com.litongjava.tio.utils.cache.CacheName
CacheNameService,使用默认的 com.litongjava.tio.utils.cache.CacheNameService
package com.litongjava.tio.web.hello.config;
import java.util.Collection;
import com.litongjava.jfinal.aop.annotation.Bean;
import com.litongjava.jfinal.aop.annotation.Configuration;
import com.litongjava.tio.utils.cache.CacheName;
import com.litongjava.tio.utils.cache.CacheNameService;
import com.litongjava.tio.utils.cache.caffeine.CaffeineCacheFactory;
import com.litongjava.tio.utils.time.Time;
@Configuration
public class CacheNameConfig {
@Bean
public CacheNameService register() {
CacheName demo = new CacheName("demo", null, Time.MINUTE_1 * 10);
CacheNameService cacheNameService = new CacheNameService();
cacheNameService.add(demo);
Collection<CacheName> names = cacheNameService.cacheNames();
for (CacheName cacheName : names) {
CaffeineCacheFactory.INSTANCE.register(cacheName);
}
return cacheNameService;
}
}
package com.litongjava.tio.web.hello.controller;
import com.litongjava.tio.http.server.annotation.RequestPath;
import com.litongjava.tio.utils.cache.CacheUtils;
import com.litongjava.tio.utils.cache.FirsthandCreater;
import com.litongjava.tio.utils.cache.ICache;
import com.litongjava.tio.utils.cache.caffeine.CaffeineCacheFactory;
import lombok.extern.slf4j.Slf4j;
@RequestPath("/cache/caffeine")
@Slf4j
public class CacheCaffeineTestController {
public Object test2() {
// firsthandCreater用户查询数据库
FirsthandCreater<String> firsthandCreater = new FirsthandCreater<String>() {
@Override
public String create() {
log.info("查询数据库");
return "index";
}
};
// 通常是tableName
String cacheName = "demo";
ICache cache = CaffeineCacheFactory.INSTANCE.getCache(cacheName);
String key = "key";
boolean putTempToCacheIfNull = false;
String value = CacheUtils.get(cache, key, putTempToCacheIfNull, firsthandCreater);
return value;
}
}
访问测试 http://localhost/cache/caffeine/test2
CacheNameService 类
- 目的: 管理缓存名称和相关设置。
- 成员变量: 包含一个
CacheName
类型的demo
对象,初始化为一个缓存名称为 "demo",生命周期为 10 分钟(Time.MINUTE_1 * 10
)的缓存。 - 方法
cacheNames()
: 返回一个包含demo
缓存配置的列表。
CacheNameConfig 类
- 目的: 配置缓存。
方法
register()
:- 创建
CacheNameService
实例。 - 遍历
cacheNames()
方法返回的所有缓存名称。 - 对每个缓存名称,使用
CaffeineCache.register
方法注册缓存,设定其生存和空闲时间。 - 返回
CacheNameService
实例。
- 创建
CacheTestController 类
- 目的: 演示如何使用缓存。
方法
test2()
:- 定义
FirsthandCreater
匿名类实例,用于在缓存未命中时获取数据(例如从数据库中)。 - 通过
Aop.get(CacheNameService.class)
获取CacheNameService
实例,并从中获取demo
缓存的名称。 - 使用
CaffeineCache.getCache
方法获取对应名称的缓存实例。 - 使用
CacheUtils.get
方法从缓存中获取键为 "key" 的数据。如果缓存中没有该数据,则会调用FirsthandCreater
实例的create
方法来获取数据并缓存它。 - 返回获取的值。
- 定义
总结
整体而言,这些代码段展示了如何在 Tio 框架中配置和使用 Caffeine 缓存。它们通过 CacheNameService
类管理缓存配置,CacheNameConfig
类负责缓存的注册,而 CacheTestController
类演示了如何实际从缓存中获取数据。这是一个典型的缓存使用场景,特别是在需要高效读取频繁访问数据的应用中。
缓存数据到 redis
使用 tio-utils 提供的 CacheUtils 缓存数据到 redis
添加依赖
因为需要使用 redisson 连接 redis,所以需要添加 redisson 依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.0</version>
</dependency>
RedissonConfig 配置类
package com.litongjava.tio.boot.hello.config;
import com.litongjava.jfinal.aop.annotation.Bean;
import com.litongjava.jfinal.aop.annotation.Configuration;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
@Configuration
public class RedissonConfig {
@Bean(destroyMethod = "shutdown", priority = 10)
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://localhost:6379").setDatabase(0);
// 如果你的 Redis 设置了密码
// .setPassword("yourPassword");
RedissonClient client = null;
try {
client = Redisson.create(config);
} catch (Exception e) {
e.printStackTrace();
}
return client;
}
}
CacheNameConfig 配置类
package com.litongjava.tio.web.hello.config;
import java.util.Collection;
import org.redisson.api.RedissonClient;
import com.litongjava.jfinal.aop.Aop;
import com.litongjava.jfinal.aop.annotation.Bean;
import com.litongjava.jfinal.aop.annotation.Configuration;
import com.litongjava.tio.utils.cache.CacheName;
import com.litongjava.tio.utils.cache.CacheNameService;
import com.litongjava.tio.utils.cache.caffeine.CaffeineCacheFactory;
import com.litongjava.tio.utils.cache.redis.RedisCacheFactory;
import com.litongjava.tio.utils.time.Time;
@Configuration
public class CacheNameConfig {
@Bean
public CacheNameService register() {
//设置CacheName
CacheName demo = new CacheName("demo", null, Time.MINUTE_1 * 10);
//将CacheName添加到CacheNameService
CacheNameService cacheNameService = new CacheNameService();
cacheNameService.add(demo);
//将redissonClient添加到RedisCacheFactory
RedissonClient redissonClient = Aop.get(RedissonClient.class);
RedisCacheFactory.INSTANCE.setRedisson(redissonClient);
//注册cacheName
Collection<CacheName> names = cacheNameService.cacheNames();
for (CacheName cacheName : names) {
CaffeineCacheFactory.INSTANCE.register(cacheName);
RedisCacheFactory.INSTANCE.register(cacheName);
}
return cacheNameService;
}
}
测试 Controller
package com.litongjava.tio.web.hello.controller;
import com.litongjava.tio.http.server.annotation.RequestPath;
import com.litongjava.tio.utils.cache.CacheUtils;
import com.litongjava.tio.utils.cache.FirsthandCreater;
import com.litongjava.tio.utils.cache.ICache;
import com.litongjava.tio.utils.cache.redis.RedisCacheFactory;
import lombok.extern.slf4j.Slf4j;
@RequestPath("/cache/redis")
@Slf4j
public class CacheRedisTestController {
public Object test3() {
// firsthandCreater用户查询数据库
FirsthandCreater<String> firsthandCreater = new FirsthandCreater<String>() {
@Override
public String create() {
log.info("查询数据库");
return "index";
}
};
String cacheName = "demo";
ICache cache = RedisCacheFactory.INSTANCE.getCache(cacheName);
String key = "key";
boolean putTempToCacheIfNull = false;
String value = CacheUtils.get(cache, key, putTempToCacheIfNull, firsthandCreater);
return value;
}
}
访问测试
http://localhost/cache/redis/test3
代码展示了如何在 Tio 框架中使用 Redis 作为缓存解决方案。以下是对代码的详细解释:
RedissonConfig 类
- 目的: 配置 Redisson 客户端以连接 Redis 服务器。
方法
redissonClient()
:- 使用
Config
类创建 Redis 配置,指定 Redis 服务器地址和数据库索引。 - 如果 Redis 设置了密码,可以通过
.setPassword("yourPassword")
方法设置。 - 创建
RedissonClient
实例并返回。 priority = 10
指定这个 Bean 的初始化优先级,值越小优先级越高,确保在其他依赖 RedissonClient 的 Bean 之前初始化。
- 使用
CacheNameConfig 类
- 目的: 配置缓存名称和设置。
方法
register()
:- 获取
RedissonClient
实例。 - 创建
CacheNameService
实例,然后获取其提供的缓存配置列表。 - 遍历列表,使用
RedisCache.register
方法为每个缓存名称注册 Redis 缓存,指定存活时间和空闲时间。 - 返回
CacheNameService
实例。
- 获取
CacheTestController 类
- 目的: 演示如何使用缓存。
方法
test3()
:- 定义
FirsthandCreater
匿名类,用于在缓存未命中时获取数据(比如从数据库获取)。 - 通过
Aop.get(CacheNameService.class)
获取CacheNameService
实例,进而获得demo
缓存的名称。 - 使用
RedisCache.getCache
方法获取对应名称的缓存实例。 - 使用
CacheUtils.get
方法从缓存中获取键为 "key" 的数据。如果缓存中没有该数据,则会调用FirsthandCreater
实例的create
方法来获取数据,并将其缓存。 - 返回获取的值。
- 定义
总结
这段代码演示了如何在 Tio 框架中配置和使用 Redis 作为缓存解决方案。它使用 RedissonClient 连接到 Redis 服务器,并通过 CacheNameService 管理缓存的不同配置。CacheTestController 类演示了如何在实际应用中从缓存中读取数据,如果缓存中没有数据,会从数据库中获取并缓存。这种方式在需要高效读取频繁访问数据的应用中非常有用。
使用 CacheUtils 整合 caffeine 和 redis 实现的两级缓存
配置类 CacheNameConfig
package com.litongjava.tio.web.hello.config;
import java.util.Collection;
import org.redisson.api.RedissonClient;
import com.litongjava.jfinal.aop.Aop;
import com.litongjava.jfinal.aop.annotation.Bean;
import com.litongjava.jfinal.aop.annotation.Configuration;
import com.litongjava.tio.utils.cache.CacheName;
import com.litongjava.tio.utils.cache.CacheNameService;
import com.litongjava.tio.utils.cache.caffeineredis.CaffeineRedisCacheFactory;
import com.litongjava.tio.utils.time.Time;
@Configuration
public class CacheNameConfig {
@Bean
public CacheNameService register() {
//设置CacheName
CacheName demo = new CacheName("demo", null, Time.MINUTE_1 * 10);
//将CacheName添加到CacheNameService
CacheNameService cacheNameService = new CacheNameService();
cacheNameService.add(demo);
//将redissonClient添加到CaffeineRedisCacheFactory
RedissonClient redissonClient = Aop.get(RedissonClient.class);
CaffeineRedisCacheFactory.INSTANCE.init(redissonClient);
//注册cacheName
Collection<CacheName> names = cacheNameService.cacheNames();
for (CacheName cacheName : names) {
//CaffeineCacheFactory.INSTANCE.register(cacheName);
//RedisCacheFactory.INSTANCE.register(cacheName);
CaffeineRedisCacheFactory.INSTANCE.register(cacheName);
}
return cacheNameService;
}
}
测试类 CacheCaffeineRedisTestController
package com.litongjava.tio.web.hello.controller;
import com.litongjava.tio.http.server.annotation.RequestPath;
import com.litongjava.tio.utils.cache.CacheUtils;
import com.litongjava.tio.utils.cache.FirsthandCreater;
import com.litongjava.tio.utils.cache.ICache;
import com.litongjava.tio.utils.cache.caffeineredis.CaffeineRedisCacheFactory;
import lombok.extern.slf4j.Slf4j;
@RequestPath("/cache/caffeine/redis")
@Slf4j
public class CacheCaffeineRedisTestController {
public Object test() {
// firsthandCreater用户查询数据库
FirsthandCreater<String> firsthandCreater = new FirsthandCreater<String>() {
@Override
public String create() {
log.info("查询数据库");
return "index";
}
};
String cacheName = "demo";
ICache cache = CaffeineRedisCacheFactory.INSTANCE.getCache(cacheName);
String key = "key";
boolean putTempToCacheIfNull = false;
String value = CacheUtils.get(cache, key, putTempToCacheIfNull, firsthandCreater);
return value;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。