依赖jar包
引入包 |
版本 |
jdk |
1.8 |
spring boot |
2.7.4 |
spring-boot-starter-data-redis |
2.7.4 |
caffeine |
2.9.3 |
allbs-common |
1.1.8 |
jackson-databind |
2.13.4.2 |
micrometer-core |
1.9.4 |
使用
添加依赖
1 2 3 4 5
| <dependency> <groupId>cn.allbs</groupId> <artifactId>allbs-cache</artifactId> <version>1.1.8</version> </dependency>
|
1
| implementation 'cn.allbs:allbs-cache:1.1.8'
|
1
| implementation("cn.allbs:allbs-cache:1.1.8")
|
说明
集成了一级caffeine和二级redisred缓存联合使用, key序列化方式为StringRedisSerializer value 序列化方式为GenericJackson2JsonRedisSerializer
开启二级缓存
添加注解@EnableAllbsCache
缓存核心配置示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| spring: cache: multi: cache-names: - allbs cache-null-values: true dynamic: true cache-prefix: ds caffeine: enable: false expire-after-access: 20m expire-after-write: 20m refresh-after-write: 20m initial-capacity: 20 maximum-size: 100 redis: enable: true default-expiration: 15s default-null-values-expiration: 15s expires: {allbs: 15s, testds:60h} topic: cache:redis:caffeine:topic
|
缓存使用
加入缓存
1 2 3 4 5 6 7 8 9 10
| @Cacheable(value = CacheConstants.TEST_2, key = "'test'") @GetMapping("/test") public String test() { String randomStr = RandomUtil.randomString(5); redisTemplate.opsForValue().set(CacheConstants.TEST_2_1, randomStr); log.info("返回结果将永远是第一次随机的数据,除非删除redis中的该key" + CacheConstants.TEST_2_1); return randomStr; }
|
加入缓存,但是每次仍然进入方法内部
移出缓存
一个方法或者类上同时指定多个Spring Cache相关的注解
redis配置示例
yml中添加如下配置,不用在启动类添加注解@EnableAllbsCache
1 2 3 4 5 6 7 8 9 10
| spring: redis: database: 0 host: ${REDIS-HOST:cq-server} port: 6379 password: ${REDIS-PWD:111111} timeout: 5000 lettuce: pool: min-idle: 2
|
自定义序列化方式说明
考虑到项目中实际使用需要使用的序列化方式与缓存不同,所以不再像此前版本定义好redis基础操作的序列化方式,由项目自主决定。同时添加配置可自定义当前项目的缓存的序列化方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| import lombok.AllArgsConstructor; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration @AllArgsConstructor @AutoConfigureBefore(RedisAutoConfiguration.class) public class RedisTemplateConfig {
@Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class)); redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class)); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; }
@Bean(name = "stringKeyRedisTemplate") public RedisTemplate<Object, Object> stringKeyRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; }
|
消息监听
只限于轻量化使用,大规模场景请使用rocketmq、rabbitmq等
方法一
自定义topic, 继承KeyspaceEventMessageListener类并实现ApplicationEventPublisherAware接口。重写doRegister、doHandleMessage、setApplicationEventPublisher方法。多个topic监听可以定义一个Topic List并放到addMessageListener中去即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class CustomMessageListener extends KeyspaceEventMessageListener implements ApplicationEventPublisherAware { private static final Topic KEYEVENT_EXPIRED_TOPIC = new ChannelTopic("自定义的topic名称"); @Nullable private ApplicationEventPublisher publisher; public CustomMessageListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override protected void doRegister(RedisMessageListenerContainer listenerContainer) { listenerContainer.addMessageListener(this, KEYEVENT_EXPIRED_TOPIC); } @Override protected void doHandleMessage(Message message) { this.publishEvent(new RedisKeyExpiredEvent(message.getBody())); } protected void publishEvent(RedisKeyExpiredEvent event) { if (this.publisher != null) { this.publisher.publishEvent(event); } } @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } }
|
方法二
接收方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Configuration @RequiredArgsConstructor @Slf4j public class CustomMessageListenerHandle {
@Bean public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(redisConnectionFactory); container.addMessageListener((message, bytes) -> { log.info("接收到监听消息"); }, new ChannelTopic("customMq")); return container; } }
|
发送方式
1
| redisTemplate.convertAndSend("自定义的topic名称", "发送内容");
|
过期key监听
继承KeyExpirationEventMessageListener重写onMessage方法即可
过期key和消息监听服务如果集群部署,或者多个服务配置了相同的监听配置,会每个服务都消费一次!!注意业务场景实际使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Component public class KeyExpirationListener extends KeyExpirationEventMessageListener { public KeyExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, @Nullable byte[] pattern) { String key = message.toString(); System.out.println("监听到key:" + key + "过期"); } }
|
发号器,使用redis实现,用于自增的企业编码、站点编码等
注入
1 2
| @Resource private IdGeneratorUtil idGeneratorUtil;
|
使用
生成id(每日重置自增序列)generateYMDId(String key, int length)
生成指定开头的自增序列 generatePreId(String key, String prefix, int length)
生成指定开头的自增序列 generatePreIdStep(String key, String prefix, int length, int step)
生成指定开头的自增序列 generatePreId(String key, String prefix, int length, int step)
指定带有前缀的发号器初始值 initGenerate(String key, String prefix, int initialValue)
指定发号器初始值 initGenerate(String key, int initialValue)