Spring cache整合redis代码实例

网友投稿 595 2023-06-08

Spring cache整合redis代码实例

Spring cache整合redis代码实例

Spring-Cache是Spring3.1引入的基于注解的缓存技术,本质上它并不是一个具体的缓存实现,而是一个对缓存使用的抽象,通过Spring AOP技术,在原有的代码上添加少量的注解来实现将这个方法转成缓存方法的效果。

本来想来个分析源码,奈何水平有限,先从实战搞起。

先引入依赖:

org.springframework.boot

spring-boot-starter-data-redis

2.1.6.RELEASE

redis.clients

jedis

2.9.3

redis配置

server:

port: 8000

spring:

redis:

host: 23.95.x.x

port: 6379

timeout: 20s

database: 0

jedis:

pool:

max-active: 5

max-idle: 3

max-wait: 5s

password: testtest

配置类:

package me.yanand.config;

import org.springframework.cache.annotation.EnableCaching;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.cache.RedisCacheConfiguration;

import org.springframework.data.redis.cache.RedisCacheManager;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.serializer.GenericJackson2jsonRedisSerializer;

import org.springframework.data.redis.serializer.RedisSerializationContext;

import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration

@EnableCaching

public class RedisConfig{

private Duration timeOut = Duration.ofMinutes(30);

@Bean

public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {

RedisCacheConfiguration config = RedisCacheConfiguration.defQFaSAcllIaultCacheConfig()

//设置缓存超时时间 30分钟

.entryTtl(timeOut)

//设置key序列化方式

.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))

//设置value序列化方式

.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))

.disableCachingNullValues();

return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).transactionAware().build();

}

}

主要看@EnableCaching注解,这个注解引入了@Import(CachingConfigurationSelector.class),通过CachingConfigurationSelector把代理创建类、CacheInterceptor、CacheOperationSource、BeanFactoryCacheOperationSourceAdvisor注入到容器,spring通过CacheInterceptor-拦截相关带有@Cacheable、@CacheEvict、@CachePut注解的方法并执行相关缓存操作。

CacheInterceptor相关源码:

@Nullable

private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {

if (contexts.QFaSAcllIisSynchronized()) {

CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();

//满足条件执行

if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {

Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);

Cache cache = context.getCaches().iterator().next();

try {

//这里主要看RedisCache的get方法

return wrapCacheValue(method, cache.get(key, () -> unwrapReturnValue(invokeOperation(invoker))));

}

catch (Cache.ValueRetrievalException ex) {

// The invoker wraps any Throwable in a ThrowableWrapper instance so we

// can just make sure that one bubbles up the stack.

throw (CacheOperationInvoker.ThrowableWrapper) ex.getCause();

}

}

else {

//不满足直接执行相关方法

return invokeOperation(invoker);

}

}

...省略

}

RedisCache相关代码:

public synchronized T get(Object key, Callable valueLoader) {

ValueWrapper result = get(key);

//缓存中有值则返回

if (result != null) {

return (T) result.get();

}

//缓存中不存在则执行相关方法

T value = valueFromLoader(key, valueLoader);

put(key, value);

return value;

}

注解使用:

package me.yanand.dao;

import me.yanand.pojo.User;

import org.springframework.cache.annotation.CacheEvict;

import org.springframework.cache.annotation.Cacheable;

import org.springframework.stereotype.Component;

@Component

public class UserDao {

@Cacheable(cacheNames = "users",key = "#root.targetClass+#name", unless = "#result eq null")

public User getUser(String name){

return new User("张三",30);

}

@CacheEvict(cacheNames = "users", key = "#root.targetClass+#name")

public void delUser(String name){

}

}

测试:

通过postman触发相关方法,现在我们连上redis查看缓存写入情况

这里我们看到key已经写入,过期时间也存在

现在我们删除缓存

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Mybatis中foreach标签带来的空格\换行\回车问题及解决方案
下一篇:Jmeter JDBC请求常见问题解决方案
相关文章

 发表评论

暂时没有评论,来抢沙发吧~